Files
2026-07-28 11:54:07 +08:00

298 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# UI 生成规则(AI JSON 生成流程 + 人类参考)
> 本文档面向“AI 根据需求生成 JSON → Unity 自动转换为 Prefab → C# 接管业务”的本项目 UI 自动生成流程。
>
> - **Part A**:整体流水线。
> - **Part B**AI 生成契约。
> - **Part C**:生成后接管与排错。
> - **Part D**:后续扩展建议。
>
> 可直接投喂 AI 的精简系统提示词见 `Client/Assets/Doc/Rule/UIGenerationPrompt.md`。
---
## Part A - 整体流水线
本项目采用 JSON-first 流程,不引入参考项目的 HTML 中间层:
```text
需求说明
-> AI 读取项目规则/设计规范/切图清单/现有 JSON 示例
-> 生成 Doc/UIPrefabCreater/{UIName}.json
-> Unity 重新获得焦点或手动菜单触发
-> JsonUIPrefabBuilder 生成 Assets/.../{UIName}.prefab
-> C# MonoBehaviour/业务代码按节点名、bindings、events 接管
```
### A1. 为什么不使用 HTML
参考项目的核心经验是“AI 产物契约 + 自动转换触发 + 自检清单”,不是 HTML 格式本身。本项目已经有 `Doc/UIPrefabCreater/*.json` 到 Prefab 的转换器,直接让 AI 输出 JSON 能减少一层转换误差,并且更贴近 Unity 的 RectTransform、组件、SpriteSwap 和 bindings/events。
### A2. 自动转换入口
转换器相关代码:
- `Client/Assets/Script/Editor/JsonUIPrefabBuilder.cs`
- `Client/Assets/Script/Editor/XWorldUtil.cs`
可用入口:
- Unity 菜单 `Tools/UI/Generate Prefab From JSON...`
- Unity 菜单 `Tools/UI/Generate All Prefabs From JSON`
- Unity 菜单 `XWorld/UI/Convert Changed JSON Prefabs Now`
- Unity 菜单 `XWorld/UI/Auto Convert JSON On Focus`
自动转换开启后,Unity 重新获得焦点时会扫描 `Doc/UIPrefabCreater`,只转换比目标 Prefab 更新的 UI JSON。
### A3. 目录约定
JSON 输入:
- `Doc/UIPrefabCreater/{UIName}.json`
通用 UI 产物:
- `Assets/Game/Art/UI/Prefab/{UIName}.prefab`
- `Assets/Game/Art/UI/Texture/Common/{sprite}.png`
- `Assets/Game/Art/UI/Font/SourceHanSansCN-Regular.otf`
小游戏专属 UI 产物:
-`UnityProject.md` 规则,将通用资源目录中的 `Game` 替换为小游戏名。
- 小游戏专属贴图不要生成到通用 `Assets/Game/...` 目录。
---
## Part B - AI 生成契约
### B1. 输入信息模板
给 AI 生成 UI 时,建议提供以下信息:
```text
界面名:
所属层级:HUD / Normal / Dialog / Tips
使用场景:
目标用户操作:
需要显示的数据:
需要点击/拖拽/输入的控件:
业务绑定节点:
事件名:
是否小游戏专属:
是否需要新贴图:
特殊适配要求:
```
### B2. 必读上下文
AI 生成前必须参考:
- `Client/Assets/Doc/Rule/UnityProject.md`
- `Doc/design/UI_Design_Principles.md`
- `Doc/design/UI_Pic_Set.md`
- `Doc/UIPrefabCreater/UI_LobbyJoystick.json`
- `Doc/UIPrefabCreater/UI_MiniGameResult.json`
- `Client/Assets/Script/Editor/JsonUIPrefabBuilder.cs` 的当前支持能力
### B3. JSON 顶层字段
| 字段 | 要求 |
| --- | --- |
| `schemaVersion` | 当前为 `1` |
| `prefabName` | 与根节点 `name` 完全一致 |
| `prefabPath` | 必须位于 `Assets/` 下 |
| `description` | 描述用途、层级、运行时绑定、特殊适配 |
| `canvas` | 必须包含 `canvasScaler.referenceResolution: [2048,1024]` |
| `assets` | 统一登记 Sprite 短名和路径 |
| `nodes` | 每个 Unity 节点一条记录 |
| `bindings` | C# 需要按名访问的节点 |
| `events` | 事件名与触发节点 |
### B4. 节点命名
节点名必须英文,便于 C# `transform.Find` 或递归查找:
| 类型 | 推荐命名 |
| --- | --- |
| 根节点 | `UI_Xxx` |
| 面板 | `Panel` / `Panel_Main` / `Panel_Content` |
| 图片 | `Img_Mask` / `Img_Bg` / `Img_Icon` |
| 文本 | `Txt_Title` / `Txt_Count` / `Txt_Desc` |
| 按钮 | `Btn_Start` / `Btn_Close` / `Btn_Ok` |
| 列表 | `Scroll_List` / `Viewport` / `Content` / `Item_Template` |
| 业务区域 | `Group_Top` / `Group_Info` / `Group_Actions` |
### B5. 当前可直接生成的组件
`JsonUIPrefabBuilder` 当前可直接创建:
- `Canvas`
- `CanvasScaler`
- `GraphicRaycaster`
- `CanvasGroup`
- `Image`
- `TextMeshProUGUI`
- `Button`
- `Shadow`
- `Outline`
- `ScrollRect`
- `RectMask2D`
- `Mask`
- `TMP_InputField`
- `VerticalLayoutGroup`
- `ContentSizeFitter`
- `LayoutElement`
- `MonoBehaviour`
项目规则文档中出现但当前转换器尚未完整实现的组件,要谨慎使用:
- `Toggle`
- `TMP_Dropdown`
- `Slider`
- `Scrollbar`
- `ScrollView`
其中 `Toggle` 当前会被识别为已知但未实现组件并跳过;`TMP_InputField` 已支持生成与绑定;`ScrollView` 应改用当前代码支持的 `ScrollRect` 结构。
### B6. 常用结构模板
#### 普通面板
- 根节点:可按需要挂 `Canvas``CanvasScaler``GraphicRaycaster`,或作为由外部 Canvas 承载的子树。
- 背景遮罩:Dialog 层使用 `Img_Mask`,全屏拉伸,Sprite `ui_overlay_dim`
- 主面板:`Panel` 使用 `ui_panel_main``ui_panel_popup``imageType: Sliced`
- 标题:`Txt_Title`,字号 36-52,根据界面层级调整。
- 内容区:`ui_panel_content`,留白不小于 24。
- 操作区:按钮组放在底部,主行为用绿色 `btn_primary_*`
#### 按钮
按钮节点通常同时包含 `Image``Button`
```json
{
"type": "Image",
"sprite": "btn_primary_normal",
"imageType": "Sliced",
"raycastTarget": true,
"color": "#FFFFFFFF"
},
{
"type": "Button",
"transition": "SpriteSwap",
"spriteHighlighted": "btn_primary_hover",
"spritePressed": "btn_primary_pressed",
"spriteDisabled": "btn_primary_disabled",
"onClick": "Example.Confirm"
}
```
按钮文字作为按钮子节点,使用 `TextMeshProUGUI`。浅色按钮文字必须加轻量 `Outline``Shadow`
#### 滚动列表
当前使用 `ScrollRect`,推荐结构:
```text
Scroll_List (Image + ScrollRect)
Viewport (Image + RectMask2D)
Content (VerticalLayoutGroup + ContentSizeFitter)
Item_Template (Image + LayoutElement, active=false)
```
`ScrollRect` 组件通过 `viewport``content` 字段引用节点名。
#### HUD
HUD 节点应尽量少用模态遮罩。角落信息使用对应角的锚点;摇杆、血条、状态条等优先使用拉伸或角锚,避免写死只适配一个屏幕比例。
---
## Part C - 生成后接管与排错
### C1. 生成后接管步骤
1. 打开 Unity,确认 JSON 自动转换是否开启,或手动执行 `XWorld/UI/Convert Changed JSON Prefabs Now`
2. 检查 Console 中 `[UIGen]` 日志,确认没有错误,警告均可解释。
3. 打开生成 Prefab,核对层级、RectTransform、Sprite、文字、按钮状态。
4. 根节点或业务节点按需挂 `MonoBehaviour` 控制器,或让 JSON 中的 `MonoBehaviour.typeName` 自动添加。
5. C# 通过 `transform.Find`、递归查找或 `Utility.FindTransform` 获取 `TextMeshProUGUI``Button``Image``RectTransform` 等组件。
6.`bindings``events` 绑定数据刷新与点击回调。
7. 运行时资源加载必须使用异步接口,不要新写同步资源加载。
### C2. 常见问题
| 现象 | 原因 | 处理 |
| --- | --- | --- |
| JSON 不转换 | 自动转换关闭、Unity 未重新获得焦点、JSON 不比 Prefab 新 | 手动执行 `Convert Changed JSON Prefabs Now` |
| `referenceResolution 必须为 [2048, 1024]` | 画布分辨率错误 | 改为 `[2048,1024]`,特殊情况写入 `description` 并同步调整转换器规则 |
| `根节点数量必须为 1` | 多个 `parent:null` | 只保留一个根节点 |
| `prefabName 必须与根节点名一致` | 顶层命名不一致 | 统一 `prefabName` 与根节点 `name` |
| `找不到 Sprite` | `assets.sprites` 短名或路径与真实切图不一致 | 按 `UI_Pic_Set.md` 校正 Sprite 名,确认图片导入为 Sprite |
| 图片存在但非 Sprite | Texture Import 设置错误 | 设置 `Texture Type = Sprite (2D and UI)` |
| Toggle 没生成 | 当前转换器未实现 | 用可视骨架替代,或补转换器 |
| TMP_InputField 文本不显示 | `textComponent` / `placeholderComponent` 指向的节点缺少 `TextMeshProUGUI` 或不在输入框下 | 修正节点名,或省略节点名让转换器自动创建 `Text Area/Text/Placeholder` |
| ScrollView 警告未知 | 当前组件名应为 `ScrollRect` | 改为 `ScrollRect`,并声明 `viewport``content` |
| 文字不可读 | 缺描边/阴影或背景对比不足 | 加 `Outline`/`Shadow`,使用 `#102033``#0B1724` |
### C3. 提交前自检
- [ ] JSON 位于 `Doc/UIPrefabCreater`
- [ ] 顶层字段完整。
- [ ] `prefabName` 与根节点名一致。
- [ ] 只有一个根节点。
- [ ] 节点名英文且不重复。
- [ ] 父节点先于子节点出现。
- [ ] `referenceResolution``[2048,1024]`
- [ ] 所有 Sprite 已登记且路径符合通用/小游戏目录规则。
- [ ] 九宫格图片使用 `Sliced`
- [ ] 文字统一 TMP,关键浅色字有轻描边或阴影。
- [ ] 按钮有 normal/hover/pressed/disabled 状态。
- [ ] `bindings``events` 中的节点真实存在。
- [ ] 不依赖未实现组件完成核心功能。
- [ ] 生成的 Prefab 在 Unity 中打开无明显重叠、越界或丢图。
---
## Part D - 后续扩展建议
### D1. 补齐转换器组件
建议优先补齐以下组件,顺序按 UI 高频程度排列:
1. `Toggle`
2. `Slider`
3. `Scrollbar`
4. `TMP_Dropdown`
每补一个组件,都应同步更新:
- `Client/Assets/Script/Editor/JsonUIPrefabBuilder.cs`
- `Client/Assets/Doc/Rule/UIGenerationPrompt.md`
- `Client/Assets/Doc/Rule/UIGenerationRules.md`
- 对应 EditMode 测试或最小 JSON 样例
### D2. 公共控件识别
参考项目的公共控件自动识别可以作为本项目下一阶段能力,但需要先定义稳定的本项目 canonical Sprite 名和空间约束。可优先考虑:
| 目标 | 识别依据 | 生成结果 |
| --- | --- | --- |
| 通用关闭按钮 | `btn_close` | 替换或规范化为关闭按钮 Prefab |
| 通用返回按钮 | `btn_back` | 替换或规范化为返回按钮 Prefab |
| 标准弹窗 | `ui_overlay_dim` + `ui_panel_popup` + `btn_close` | 标准 Dialog Prefab |
| 资源条 | `ico_coin` / `ico_diamond` + 数值 + `ico_plus` | 标准 Currency 组件 |
| Toast | `toast_bg` + 文本 | 标准 Tips 组件 |
识别器必须保守:缺件、歧义、跨区域时保留原节点并输出 Warning,不要误合并。
### D3. AI 生成质量评审
AI 产出的 UI JSON 应优先检查三件事:
1. **工程可转换**:字段、父子关系、组件名、Sprite 名都能被当前工具处理。
2. **视觉一致**:符合糖果风、配色语义、九宫格、TMP 和可读性规则。
3. **业务可接管**:节点命名稳定,bindings/events 完整,C# 能按名找到控件。
只要这三件事成立,生成的 Prefab 就可以作为程序接管的稳定 UI 骨架。