# 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 骨架。