# UI界面拼接设计指南 ## 一、界面结构设计原则 ### 1.1 模块化拆分 将界面按功能划分为独立模块: | 模块类型 | 功能定位 | 示例 | |---------|---------|------| | **信息展示区** | 显示玩家状态、资源等静态信息 | 顶部信息栏、左侧状态栏 | | **功能入口区** | 提供功能按钮入口 | 中央功能区、底部快捷栏 | | **交互面板区** | 可展开/收起的功能面板 | 右侧功能面板、顶部按钮区 | | **输入输出区** | 用户输入和系统反馈 | 聊天输入框、提示信息 | ### 1.2 经典布局模式 ``` ┌─────────────────────────────────────────────────────┐ │ TopArea (信息展示 + 可收起功能按钮) │ ├──────────┬───────────────────────┬──────────────────┤ │ Left │ │ Right │ │ Area │ CenterArea │ Area │ │ (状态) │ (核心功能入口) │ (功能面板) │ │ │ │ │ ├──────────┴───────────────────────┴──────────────────┤ │ BottomArea (快捷功能 + 状态信息 + 输入) │ └─────────────────────────────────────────────────────┘ ``` --- ## 二、组件拆分方法 ### 2.1 基础组件识别 | 组件类型 | 识别特征 | 处理方式 | |---------|---------|---------| | **按钮** | 可点击、有交互反馈 | 使用 `SFUI_Button` | | **文本** | 静态/动态文字显示 | 使用 `SFUI_TextMeshProUGUI` | | **图片** | 图标、背景图 | 使用 `SFUI_Image` | | **进度条** | HP、MP、经验等 | 使用 `SFUI_Slider` | | **列表** | 可滚动的项目列表 | 使用 `SFUI_ScrollRect` | ### 2.2 复合组件封装 将功能相关的基础组件组合为复合组件,便于复用和维护: **设计原则**: - 将同一功能模块的组件封装在一起(如玩家头像+血条+蓝条) - 提供统一的数据设置接口 - 保持组件之间的逻辑独立性 --- ## 三、预制体层级规范 ### 3.1 标准层级结构 ``` WindowName (RectTransform) ├── ModuleName (RectTransform) # 模块容器 │ ├── ComponentName (SFUI_*) # 功能组件 │ ├── SubModule (RectTransform) # 子模块 │ └── CollapsibleArea (RectTransform) # 可收起区域 └── BtnCollapse (SFUI_Button) # 收起控制按钮 ``` ### 3.2 命名规范 | 类型 | 命名规则 | 示例 | |-----|---------|------| | 模块容器 | PascalCase + Area | `TopArea` | | 功能组件 | PascalCase | `BtnCollapseTop` | | 可收起区域 | PascalCase + FuncArea | `TopFuncArea` | | 状态变量 | m_ + PascalCase | `m_IsTopCollapsed` | --- ## 四、收起/展开功能设计 ### 4.1 功能定义 | 按钮 | 控制区域 | 用途 | |-----|---------|------| | `BtnCollapseTop` | 顶部功能按钮区 | 收起/展开顶部按钮群 | | `BtnCollapseRight` | 右侧功能面板区 | 收起/展开右侧功能面板 | ### 4.2 设计要点 **状态管理**:每个可收起区域需要一个布尔状态变量来记录当前收起/展开状态。 **交互逻辑**: 1. 点击收起按钮时,切换对应区域的显示/隐藏状态 2. 同时切换按钮图标(收起时显示展开图标,展开时显示收起图标) **布局要求**: - 收起按钮应放置在对应区域的边缘位置,便于用户找到 - 收起区域内的所有元素应作为一个整体进行显示/隐藏控制 - 收起状态应在窗口生命周期内保持记忆 --- ## 五、实际案例:主界面拼接 ### 5.1 模块化设计思想 **核心原则**:将界面按功能边界划分为独立模块,模块内可嵌套子模块。 **模块归类方法**: 1. **一级模块**:按空间位置划分(顶部、左侧、中央、右侧、底部) 2. **二级模块**:按功能类型划分(信息展示区、功能按钮区、输入输出区) 3. **三级模块**:按具体功能划分(玩家头像、资源显示、功能按钮群) **层级关系示例**: ``` Window ├── TopArea (一级:位置) │ ├── InfoPanel (二级:信息展示) │ │ └── TxtWelcome (三级:具体组件) │ └── FuncButtons (二级:功能按钮) │ └── BtnUpload (三级:具体按钮) └── LeftArea (一级:位置) └── PlayerPortrait (二级:复合组件) ├── ImgAvatar (三级:头像) └── BarHP (三级:血条) ``` **设计要点**: - 同一功能域内的元素归为同一模块(如头像、血条、蓝条归为玩家状态模块) - 独立交互功能作为独立模块(如收起按钮单独作为控制模块) - 可收起区域作为独立子模块,便于统一控制显示/隐藏 --- ## 六、界面拼接流程 ### 6.1 设计阶段 1. **需求分析**:明确界面功能和交互需求 2. **模块划分**:将界面拆分为独立功能模块 3. **层级设计**:设计预制体层级结构 ### 6.2 开发阶段 1. **组件创建**:创建基础组件和复合组件 2. **预制体搭建**:按层级结构搭建预制体 3. **脚本编写**:实现交互逻辑和收起/展开功能 ### 6.3 测试阶段 1. **功能测试**:验证所有按钮和交互功能 2. **收起测试**:测试收起/展开功能正常工作 3. **适配测试**:验证不同分辨率下的显示效果 --- ## 七、注意事项 1. **组件复用**:相同功能的组件尽量复用,减少冗余 2. **状态管理**:收起状态需要正确保存和恢复 3. **图标反馈**:收起按钮图标应随状态变化 4. **性能优化**:可收起区域使用 `SetActive` 而非销毁重建 5. **命名规范**:统一的命名规则便于维护和查找 --- ## 八、JSON配置驱动的UI生成方式 ### 8.1 概述 **UI相关人员核心工作流程**:读取设计效果图和碎片图片,生成JSON配置文件,再通过工具自动生成Unity预制体。 本项目支持JSON配置与Unity预制体的双向转换: - **正向转换**:JSON配置 → UI预制体(核心流程) - **反向转换**:UI预制体 → JSON配置(辅助流程) 实现UI界面的快速构建、迭代和版本控制。 ### 8.2 核心组件 | 组件 | 职责 | 文件路径 | |-----|------|---------| | **UIPrefabGenerator** | 解析JSON并生成UI预制体 | `Assets/Editor/Command/UIPrefabGenerator.cs` | | **UIPrefabToJson** | 从预制体反向导出JSON | `Assets/Editor/Command/UIPrefabToJson.cs` | | **RemoteCommand** | 提供外部调用接口 | `Assets/Editor/Command/RemoteCommand.cs` | | **ExternalCommandListener** | 监听外部命令触发文件 | `Assets/Editor/Command/ExternalCommandListener.cs` | ### 8.3 JSON配置文件结构 ```json { "name": "BagWindow", "width": 1024, "height": 768, "elements": [ { "type": "Image", "name": "BgPanel", "anchorMin": [0, 0], "anchorMax": [1, 1], "position": [0, 0, 0], "sizeDelta": [0, 0], "sprite": "Assets/Game/GameHFResource/CN/UIWindows/BagWindow/Sprites/Bg.png" }, { "type": "Text", "name": "TitleText", "anchorMin": [0.5, 0.9], "anchorMax": [0.5, 0.9], "position": [0, 0, 0], "sizeDelta": [200, 40], "text": "背包", "font": "Assets/Game/GameHFResource/CN/Fonts/FZY4K-M05S SDF.asset", "fontSize": 28, "color": [1, 1, 1, 1] } ] } ``` ### 8.4 支持的UI元素类型 | 类型 | 对应Unity组件 | 关键属性 | |-----|-------------|---------| | **Image** | Image | sprite, color, type, preserveAspect | | **TextMeshProUGUI** | TextMeshProUGUI | text, font, fontSize, color, alignment | | **Button** | Button | interactable, transition, navigationMode | | **Slider** | Slider | minValue, maxValue, value, wholeNumbers, direction | | **Toggle** | Toggle | isOn, toggleTransition, transition | | **InputField** | InputField | text, placeholder, characterLimit, contentType | | **ScrollRect** | ScrollRect | horizontal, vertical, movementType | | **GridLayoutGroup** | GridLayoutGroup | cellSize, spacing, constraint, padding | | **VerticalLayoutGroup** | VerticalLayoutGroup | spacing, childAlignment, padding | | **HorizontalLayoutGroup** | HorizontalLayoutGroup | spacing, childAlignment, padding | ### 8.5 外部命令触发机制 #### 8.5.1 触发方式 通过创建/修改 `Trigger_Command.txt` 文件触发UI生成: ``` GenerateUIPrefab:Assets/Editor/UI/BagWindow.json ``` #### 8.5.2 命令格式 ``` <命令名>:<参数1>:<参数2>:... ``` **支持的命令**: | 命令 | 参数 | 说明 | |-----|------|------| | **GenerateUIPrefab** | `jsonPath` [, `prefabPath`] | 根据JSON生成UI预制体 | | **ExportPrefabToJson** | `prefabPath` [, `jsonPath`] | 从预制体反向导出JSON | | **ReadJson** | [参数列表] | 读取JSON配置(测试用) | #### 8.5.3 完整执行流程 ``` ┌─────────────────────────────────────────────────────────────────────┐ │ 外部系统写入命令到 Trigger_Command.txt │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ ExternalCommandListener (FileSystemWatcher) 检测到文件变化 │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 解析命令格式:GenerateUIPrefab:Assets/Editor/UI/BagWindow.json │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 通过反射调用 RemoteCommand.GenerateUIPrefab(string[] args) │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ UIPrefabGenerator.GeneratePrefabFromJson(jsonPath, prefabPath) │ └─────────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────────┐ │ 生成预制体到指定路径:Assets/Game/GameHFResource/CN/UIWindows/... │ └─────────────────────────────────────────────────────────────────────┘ ``` ### 8.6 Unity编辑器菜单测试 在Unity编辑器中提供了测试菜单: | 菜单路径 | 功能 | |---------|------| | `Tools > UI > Export Prefab to JSON` | 选择预制体导出JSON | | `Tools > UI > Generate BagWindow Prefab` | 生成BagWindow预制体 | | `Tools > External > Test ReadJson` | 测试ReadJson命令 | | `Tools > External > Test GenerateUIPrefab` | 测试正向生成 | | `Tools > External > Test ExportPrefabToJson` | 测试反向导出 | ### 8.7 使用示例 #### 方式一:外部命令触发 ```bash # 正向:从JSON生成预制体 echo "GenerateUIPrefab:Assets/Editor/UI/BagWindow.json" > "F:\JMNet\CrystalBattle_Client\Trigger_Command.txt" # 反向:从预制体导出JSON echo "ExportPrefabToJson:Assets/Game/GameHFResource/CN/UIWindows/BagWindow/BagWindow.prefab" > "F:\JMNet\CrystalBattle_Client\Trigger_Command.txt" ``` #### 方式二:Unity编辑器菜单 **正向生成**: 1. 打开Unity编辑器 2. 点击菜单 `Tools > External > Test GenerateUIPrefab` 3. 查看Console窗口日志确认执行结果 **反向导出**: 1. 打开Unity编辑器 2. 点击菜单 `Tools > UI > Export Prefab to JSON` 3. 选择要导出的预制体文件 #### 方式三:代码调用 ```csharp // 正向:从JSON生成预制体 UIPrefabGenerator.GeneratePrefabFromJson( "Assets/Editor/UI/BagWindow.json", "Assets/Game/GameHFResource/CN/UIWindows/BagWindow/BagWindow.prefab" ); // 反向:从预制体导出JSON UIPrefabToJson.ExportPrefabToJson( "Assets/Game/GameHFResource/CN/UIWindows/BagWindow/BagWindow.prefab", "Assets/Editor/UI/BagWindow.json" ); ``` ### 8.8 注意事项 1. **路径格式**:JSON中的资源路径使用 `/` 分隔符,且为Unity项目相对路径 2. **资源引用**:确保JSON中引用的Sprite、Font等资源已存在于项目中 3. **编码格式**:JSON文件使用UTF-8编码 4. **坐标系统**:使用Unity RectTransform的anchorMin/anchorMax/position/sizeDelta四元组 5. **文件锁定**:生成前确保目标预制体文件未被其他进程占用 ### 8.9 工具脚本部署 #### 8.9.1 工具位置 工具脚本位于UnityAI文档库的以下路径: ``` UnityAI/06_工具脚本/UI工具/ ├── ExternalCommandListener.cs # 外部命令监听器 ├── RemoteCommand.cs # 远程命令接口 ├── UIPrefabGenerator.cs # JSON转预制体生成器 └── UIPrefabToJson.cs # 预制体转JSON导出器 ``` #### 8.9.2 部署步骤 **方法一:手动复制** 1. 复制 `06_工具脚本/UI工具/` 目录下的所有文件 2. 粘贴到目标项目的 `Assets/Editor/Command/` 目录中 3. 确保目录结构如下: ``` Assets/Editor/Command/ ├── ExternalCommandListener.cs ├── RemoteCommand.cs ├── UIPrefabGenerator.cs └── UIPrefabToJson.cs ``` **方法二:自动部署脚本** 创建部署脚本 `DeployUITools.bat`: ```batch @echo off set "SOURCE_DIR=E:\AI\UnityAI\06_工具脚本\UI工具" set "TARGET_DIR=%cd%\Assets\Editor\Command" mkdir "%TARGET_DIR%" 2>nul xcopy "%SOURCE_DIR%\*.cs" "%TARGET_DIR%\" /y xcopy "%SOURCE_DIR%\*.cs.meta" "%TARGET_DIR%\" /y echo UI工具部署完成 pause ``` #### 8.9.3 部署规则 | 检查项 | 要求 | |-------|------| | **目标路径** | 必须放置在 `Assets/Editor/Command/` 目录下 | | **文件完整性** | 必须包含所有4个cs文件及其meta文件 | | **Unity版本** | 支持Unity 2020及以上版本 | | **依赖组件** | 需要导入 TextMeshPro 包 | #### 8.9.4 验证部署 部署完成后,在Unity编辑器中验证: 1. 打开Unity编辑器 2. 检查菜单 `Tools > UI` 是否存在 3. 检查菜单 `Tools > External` 是否存在 4. 在Console窗口确认无编译错误 --- **版本**: v1.2 **适用**: StrayFog框架UI拼接开发人员