【整合】 框架使用规则
This commit is contained in:
@@ -1,176 +1,106 @@
|
||||
# CrystalBattle Codex ↔ Unity MCP 使用规则
|
||||
# CrystalBattle Codex 与 Unity MCP 使用规则
|
||||
|
||||
## 1. 目标与定位
|
||||
## 一、定位
|
||||
|
||||
MCP(Model Context Protocol)用于打通 Codex 与 Unity Editor。Codex 不直接操作 Unity 进程,而是通过本地 MCP Server 调用 Unity Editor 内的 HTTP Bridge,再由 Bridge 在 Unity 主线程执行 Editor 命令。
|
||||
Codex 通过本地 stdio MCP Server 调用 Unity Editor 内的 HTTP Bridge。Bridge 只监听 `127.0.0.1:17777`,并把 Unity API 工作排队到 Editor 主线程执行。
|
||||
|
||||
当前首版定位:
|
||||
当前能力只面向 Unity Editor 自动化,不覆盖 Play Mode、真机运行时调试或远程网络访问。
|
||||
|
||||
- 只支持 Unity Editor 工具桥,不覆盖 Play Mode 或真机运行时调试。
|
||||
- 只监听本机 `127.0.0.1`,不开放局域网访问。
|
||||
- 优先服务 UI 生成、Prefab 导出、资源刷新、日志读取等 Editor 自动化流程。
|
||||
- Proxima 暂不作为 MCP 主通道,后续如做运行时调试再单独规划。
|
||||
|
||||
## 2. 工程结构
|
||||
|
||||
本文档只说明 Codex 如何对接 Unity MCP,不说明 Unity Editor 内部脚本目录结构,也不在本节维护数据目录。
|
||||
|
||||
Codex 需要知道的对接点:
|
||||
## 二、对接点
|
||||
|
||||
```text
|
||||
Unity MCP Server: UnityAI/Tools/CodexUnityMcp/
|
||||
MCP Server: UnityAI/Tools/CodexUnityMcp/
|
||||
Codex config: .codex/config.toml
|
||||
Unity Bridge URL: http://127.0.0.1:17777
|
||||
Unity Bridge: http://127.0.0.1:17777
|
||||
```
|
||||
|
||||
## 3. 启动与连接
|
||||
本文档不维护 Unity Bridge 的打开方式或 Unity Editor 内部目录结构。
|
||||
|
||||
1. 确认 `.codex/config.toml` 中存在 `crystalbattle-unity` MCP server 配置。
|
||||
2. 确认 MCP Server 入口指向 `UnityAI/Tools/CodexUnityMcp/src/server.mjs`。
|
||||
3. Codex 侧重启或新开线程后,会重新读取 MCP server 配置。
|
||||
4. 每轮 Unity 自动化前,优先调用 `unity_health` 检查连通性。
|
||||
5. 如果 `unity_health` 不通,只记录错误并停止后续 Unity 操作;Unity 侧如何打开或重启 Bridge 不在本文档说明范围内。
|
||||
## 三、可用工具
|
||||
|
||||
禁止事项:
|
||||
| 工具 | 用途 |
|
||||
|---|---|
|
||||
| `unity_health` | 检查 Bridge、项目路径和 Unity 版本 |
|
||||
| `unity_refresh_assets` | 执行 `AssetDatabase.Refresh()` |
|
||||
| `unity_execute_menu_item` | 执行 Bridge 白名单中的菜单项 |
|
||||
| `unity_get_console_logs` | 读取最近 Unity Console 日志 |
|
||||
| `unity_generate_ui_prefab` | 根据 JSON 生成 UI Prefab |
|
||||
| `unity_export_prefab_to_json` | 将 UI Prefab 导出为 JSON |
|
||||
|
||||
- 不允许把 Bridge 地址改成 `0.0.0.0` 或局域网 IP。
|
||||
- 不允许绕过 MCP 直接让 Codex 执行 Unity Editor 侧业务逻辑。
|
||||
- 不允许在 Unity 后台线程直接调用 Unity API,所有 Unity API 必须回到 Editor 主线程执行。
|
||||
`unity_execute_menu_item` 不能执行任意菜单。新增菜单能力时必须同时修改 Bridge 白名单并验证风险。
|
||||
|
||||
## 4. Codex 可用工具
|
||||
## 四、标准调用流程
|
||||
|
||||
| 工具名 | 用途 | 规则 |
|
||||
|---|---|---|
|
||||
| `unity_health` | 检查 Unity Bridge 是否在线 | 每轮 Unity 自动化前优先调用 |
|
||||
| `unity_refresh_assets` | 执行 `AssetDatabase.Refresh()` | 生成或导出资源后可调用 |
|
||||
| `unity_execute_menu_item` | 执行白名单菜单项 | 只能执行 Bridge 内白名单 |
|
||||
| `unity_get_console_logs` | 读取最近 Unity Console 日志 | 生成失败或验证结果时必须查看 |
|
||||
| `unity_generate_ui_prefab` | 根据 JSON 生成 UI Prefab | 输入 JSON 必须使用 Unity 工程相对路径或绝对路径 |
|
||||
| `unity_export_prefab_to_json` | 从 UI Prefab 导出 JSON | Prefab 路径必须是 Unity Asset 路径 |
|
||||
1. 每轮 Unity 自动化前先调用 `unity_health`。
|
||||
2. 确认返回的项目路径就是当前目标工程。
|
||||
3. 执行当前任务需要的最少工具调用。
|
||||
4. 资源变化后调用 `unity_refresh_assets`。
|
||||
5. 调用 `unity_get_console_logs` 检查新增 Error 和关键 Warning。
|
||||
6. Prefab/UI 继续做结构和实际显示验证,不能只确认命令返回成功。
|
||||
|
||||
## 5. MCP 数据目录规则
|
||||
`unity_health` 失败时停止后续 Unity 命令并报告错误,不假设 Bridge 已经执行任何操作。
|
||||
|
||||
所有 MCP 数据必须按功能单独放在 Unity Editor 目录下,并直接按目标预制体名分文件夹;不再增加中间层目录。统一格式:
|
||||
## 五、UI 生成
|
||||
|
||||
```text
|
||||
Assets/Editor/MCP_{功能名}/<PrefabName>/
|
||||
```
|
||||
UI 任务必须先从 [UnityAI README](../../../../README.md) 进入 UI 文档,并阅读:
|
||||
|
||||
命名要求:
|
||||
- [UI 开发指南](../../UI窗口系统/开发指南.md)
|
||||
- [UI 界面拼接](../../UI窗口系统/界面拼接.md)
|
||||
- [UI 拼接工具](../UI拼接工具.md)
|
||||
|
||||
- `{功能名}` 只表示功能类别,不写具体窗口名、临时任务名或个人名。
|
||||
- `<PrefabName>` 必须沿用目标预制体名称,和最终生成的 `<PrefabName>.prefab` 保持一致。
|
||||
- UI 相关数据统一放在 `Assets/Editor/MCP_UI/<PrefabName>/`。
|
||||
- 其它功能按能力命名,例如 `Assets/Editor/MCP_Config/<PrefabName>/`、`Assets/Editor/MCP_Map/<PrefabName>/`。
|
||||
- 新增、导出、临时验证用 JSON 都必须遵守该目录规则。
|
||||
随后按以下步骤执行:
|
||||
|
||||
整理旧数据时,应迁移到 `Assets/Editor/MCP_UI/<PrefabName>/` 或对应功能目录。
|
||||
1. 检查设计图、目标 Prefab、窗口脚本和现有资源。
|
||||
2. 明确传入 JSON 路径和目标 Prefab 路径。
|
||||
3. 调用 `unity_generate_ui_prefab`。
|
||||
4. 刷新 Assets 并读取 Console。
|
||||
5. 检查 Prefab 层级、RectTransform、组件状态和资源引用。
|
||||
6. 需要核对双向转换时调用 `unity_export_prefab_to_json`。
|
||||
7. 在 Unity 运行环境验证实际显示和交互。
|
||||
|
||||
## 6. UI 生成规则
|
||||
不规定固定测试目录、测试窗口名或中间数据目录。任务产生的路径由调用方明确提供,覆盖正式 Prefab 前必须确认。
|
||||
|
||||
标准流程:
|
||||
## 六、安全边界
|
||||
|
||||
1. 先读取 `UnityAI/README.md` 中的 UI 相关索引。
|
||||
2. 根据 README 的 UI 相关入口,优先阅读:
|
||||
- `UnityAI/modules/frameworks/UI窗口系统/开发指南.md`
|
||||
- `UnityAI/modules/frameworks/UI窗口系统/界面拼接.md`
|
||||
3. 需要使用 JSON 与 Prefab 双向转换时,再阅读 README 中的 `编辑器工具脚本` 入口:
|
||||
- `UnityAI/modules/frameworks/编辑器工具/UI工具/`
|
||||
4. 按 UI 指南确认窗口命名、层级、资源路径和布局规则后,准备 UI JSON。
|
||||
5. 调用 `unity_generate_ui_prefab`。
|
||||
6. 目标 Prefab 路径优先使用:
|
||||
- Bridge 只监听 `127.0.0.1`,禁止改为 `0.0.0.0` 或局域网地址。
|
||||
- MCP Server 不直接操作 Unity 资源,资源变更交给 Unity Bridge。
|
||||
- HTTP 线程只接收和返回数据,Unity API 回到主线程执行。
|
||||
- 不开放任意菜单、任意 C# 执行、批量删除、构建发布或 Git 操作。
|
||||
- 生成和导出只修改调用参数明确指定的目标。
|
||||
- 日志和错误返回包含命令、路径和失败原因,不返回无上下文的“失败”。
|
||||
|
||||
```text
|
||||
Assets/Game/GameHFResource/CN/UIWindows/<WindowName>/<WindowName>.prefab
|
||||
```
|
||||
## 七、排错
|
||||
|
||||
7. 调用 `unity_get_console_logs` 查看是否有 Error 或关键 Warning。
|
||||
8. 如需要验证双向转换,再调用 `unity_export_prefab_to_json`。
|
||||
### 连接失败
|
||||
|
||||
JSON 约束:
|
||||
1. 调用 `unity_health` 保留原始错误。
|
||||
2. 检查 `.codex/config.toml` 的 Node command 和 server 入口。
|
||||
3. 确认 `Tools/CodexUnityMcp` 依赖已经安装。
|
||||
4. 连接恢复前不执行其他 Unity 工具。
|
||||
|
||||
- 根对象使用 `UILayoutData` 结构:`name/type/layer/rectTransform/canvas/children`。
|
||||
- UI 节点使用 `UIElementData` 结构:`name/type/rectTransform/image/button/text/.../children`。
|
||||
- 资源路径使用 Unity Asset 路径,例如 `Assets/...`。
|
||||
- 测试 UI 命名必须带明确测试标识,例如 `CodexMcpTestWindow`。
|
||||
### 端口占用
|
||||
|
||||
当前注意事项:
|
||||
- Bridge 如果发现同端口已经存在有效服务,应连接到现有监听状态而不是重复启动。
|
||||
- 不能通过同时启动多个监听器解决端口冲突。
|
||||
- 状态仍不一致时记录端口、进程和 Bridge 状态,再处理占用来源。
|
||||
|
||||
- `UnityEngine.JsonUtility` 解析递归 `children` 结构时可能出现 serialization depth warning。
|
||||
- 如果 Prefab 已成功生成且没有 Error,该 warning 暂不阻塞测试。
|
||||
- 后续如大量使用 UI JSON,应考虑把解析器替换为更适合递归结构的 JSON 库。
|
||||
### UI 生成失败
|
||||
|
||||
## 7. 安全与权限
|
||||
1. 读取 Unity Console。
|
||||
2. 检查 JSON 和目标路径是否存在且格式正确。
|
||||
3. 检查 Sprite、Font、Material 等 Asset 路径。
|
||||
4. 检查 `rectTransform`、递归 `children` 和组件字段。
|
||||
5. 检查目标 Prefab 是否被错误覆盖或无法写入。
|
||||
|
||||
MCP 工具可以触发 Unity Editor 行为,因此必须保持最小权限:
|
||||
## 八、维护
|
||||
|
||||
- `execute_menu_item` 必须使用白名单,禁止开放任意菜单执行。
|
||||
- 只允许监听 `127.0.0.1`。
|
||||
- 不在 MCP Server 中直接读写 Unity 资源,资源变更统一交给 Unity Bridge 执行。
|
||||
- 生成测试资源时使用独立测试目录或明确测试命名,避免覆盖正式 UI。
|
||||
- 覆盖已有 Prefab 前必须确认目标路径是否为预期文件。
|
||||
- 不通过 MCP 执行批量删除、批量移动、构建发布、Git 操作等高风险动作。
|
||||
新增 MCP tool 时同步更新:
|
||||
|
||||
## 8. 排错流程
|
||||
- `Tools/CodexUnityMcp/src/server.mjs`
|
||||
- Unity Bridge 对应命令
|
||||
- 本文档工具列表和验证步骤
|
||||
|
||||
连接失败:
|
||||
|
||||
1. 调用 `unity_health` 获取错误信息。
|
||||
2. 用浏览器或 PowerShell 检查:
|
||||
|
||||
```powershell
|
||||
Invoke-WebRequest -UseBasicParsing "http://127.0.0.1:17777/health"
|
||||
```
|
||||
|
||||
3. 如果连接仍失败,停止后续 Unity 操作并记录错误;Unity 侧启动、重启、面板操作不在本文档说明范围内。
|
||||
|
||||
MCP 工具不可见:
|
||||
|
||||
1. 确认 `UnityAI/Tools/CodexUnityMcp/node_modules` 已安装。
|
||||
2. 确认 `.codex/config.toml` 中 `command` 和 `args` 路径有效。
|
||||
3. 重启 Codex,让 MCP server 配置重新加载。
|
||||
|
||||
UI 生成失败:
|
||||
|
||||
1. 调用 `unity_get_console_logs` 查看 Unity Console。
|
||||
2. 检查 JSON 文件是否存在。
|
||||
3. 检查 JSON 是否位于 `Assets/Editor/MCP_UI/<PrefabName>/`。
|
||||
4. 检查 `rectTransform` 数组字段是否齐全。
|
||||
5. 检查 Sprite、Font、Material 等资源路径是否存在。
|
||||
6. 确认 Prefab 目标目录可写且未被外部程序锁定。
|
||||
|
||||
## 9. 测试基准
|
||||
|
||||
每次修改 MCP 或 Unity Bridge 后,至少验证:
|
||||
|
||||
- `unity_health` 返回 `ok=true`。
|
||||
- `unity_get_console_logs` 能返回日志。
|
||||
- `unity_generate_ui_prefab` 能生成一个最小测试 Prefab。
|
||||
- 生成的 Prefab 文件存在,并包含预期节点名。
|
||||
- `unity_export_prefab_to_json` 能把测试 Prefab 导出 JSON。
|
||||
- Unity Console 无新增 Error。
|
||||
|
||||
UI 测试样例推荐路径:
|
||||
|
||||
```text
|
||||
Assets/Editor/MCP_UI/CodexMcpTestWindow/CodexMcpTestWindow.json
|
||||
Assets/Game/GameHFResource/CN/UIWindows/CodexMcpTestWindow/CodexMcpTestWindow.prefab
|
||||
Assets/Editor/MCP_UI/CodexMcpTestWindow/CodexMcpTestWindow.exported.json
|
||||
```
|
||||
|
||||
## 10. 维护规则
|
||||
|
||||
新增 MCP tool 时必须同步更新:
|
||||
|
||||
- `UnityAI/Tools/CodexUnityMcp/src/server.mjs`
|
||||
- Unity Bridge 侧对应命令代码
|
||||
- 本文档的工具列表与测试基准
|
||||
|
||||
新增 Unity 命令时必须满足:
|
||||
|
||||
- HTTP 请求只负责收包和回包。
|
||||
- Unity API 在 `EditorApplication.update` 主线程队列执行。
|
||||
- 返回值使用统一结构:
|
||||
Bridge 返回统一结构:
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -181,25 +111,13 @@ Assets/Editor/MCP_UI/CodexMcpTestWindow/CodexMcpTestWindow.exported.json
|
||||
}
|
||||
```
|
||||
|
||||
文档版本:
|
||||
|
||||
- v1.4
|
||||
- 生效日期:2026-07-03
|
||||
- 适用项目:CrystalBattle_Client
|
||||
|
||||
---
|
||||
|
||||
## 文档关联
|
||||
|
||||
> 当本文档发生变更时,应同步检查以下关联文档,避免信息不一致。
|
||||
|
||||
| 文档 | 关联原因 |
|
||||
|---|---|
|
||||
| [MCP 工具入口](README.md) | 本文件是 MCP 工具模块的子文档 |
|
||||
| [UI 开发指南](../../UI窗口系统/开发指南.md) | UI 生成规则参考 |
|
||||
| [UI 界面拼接设计指南](../../UI窗口系统/界面拼接.md) | UI 布局规则参考 |
|
||||
| [UI 拼接工具](../UI拼接工具.md) | JSON/Prefab 双向转换工具说明 |
|
||||
| [Tools/CodexUnityMcp](../../../../Tools/CodexUnityMcp/README.md) | MCP Server 实现 |
|
||||
| [modules/模块索引.md](../../../模块索引.md) | 模块索引是项目知识总入口 |
|
||||
| [rules/10-架构说明.md](../../../../rules/10-架构说明.md) | 编辑器工具层的架构说明 |
|
||||
| [rules/30-模块登记规则.md](../../../../rules/30-模块登记规则.md) | 模块登记规则定义分类和状态口径 |
|
||||
| [MCP 工具入口](README.md) | MCP 模块入口 |
|
||||
| [UI 开发指南](../../UI窗口系统/开发指南.md) | UI 生命周期和列表规则 |
|
||||
| [UI 界面拼接](../../UI窗口系统/界面拼接.md) | Prefab 拼接流程 |
|
||||
| [UI 拼接工具](../UI拼接工具.md) | JSON/Prefab 工具结构 |
|
||||
| [MCP Server README](../../../../Tools/CodexUnityMcp/README.md) | Server 安装和实现 |
|
||||
| [工作流清单](../../../../rules/40-工作流清单.md) | Unity/MCP 验证流程 |
|
||||
|
||||
@@ -1,28 +1,31 @@
|
||||
# MCP工具
|
||||
# MCP 工具
|
||||
|
||||
本目录用于沉淀 Codex 与 Unity Editor 打通相关的规则、工具说明和排错流程。
|
||||
Codex 通过本地 Node MCP Server 与 Unity Editor Bridge 交互,当前实现已经在 CrystalBattle_Client 验证。
|
||||
|
||||
当前文档:
|
||||
## 实现位置
|
||||
|
||||
- [CrystalBattle Codex ↔ Unity MCP 使用规则](CrystalBattle_Codex_Unity_MCP使用规则.md)
|
||||
|
||||
当前实现位置:
|
||||
|
||||
- Unity Editor Bridge:`CrystalBattle_Client/Assets/Editor/Command/`
|
||||
- MCP Server:`UnityAI/Tools/CodexUnityMcp/`
|
||||
- Codex 配置:`.codex/config.toml`
|
||||
- Unity Editor Bridge:目标项目 `Assets/Editor/Command/`
|
||||
- Codex 配置:工作区 `.codex/config.toml`
|
||||
- 本地地址:`http://127.0.0.1:17777`
|
||||
|
||||
---
|
||||
## 能力
|
||||
|
||||
- Unity 健康检查
|
||||
- AssetDatabase 刷新
|
||||
- 白名单菜单执行
|
||||
- Console 日志读取
|
||||
- UI JSON 生成 Prefab
|
||||
- Prefab 导出 JSON
|
||||
|
||||
具体调用、UI 前置阅读、安全边界和排错见 [CrystalBattle Codex 与 Unity MCP 使用规则](CrystalBattle_Codex_Unity_MCP使用规则.md)。
|
||||
|
||||
## 文档关联
|
||||
|
||||
> 当本文档发生变更时,应同步检查以下关联文档,避免信息不一致。
|
||||
|
||||
| 文档 | 关联原因 |
|
||||
|---|---|
|
||||
| [编辑器工具入口](../README.md) | 本文件是编辑器工具模块的子文档 |
|
||||
| [CrystalBattle Codex ↔ Unity MCP 使用规则](CrystalBattle_Codex_Unity_MCP使用规则.md) | 具体 MCP 使用规则 |
|
||||
| [Tools/CodexUnityMcp](../../../../Tools/CodexUnityMcp/README.md) | MCP Server 实现 |
|
||||
| [modules/模块索引.md](../../../模块索引.md) | 模块索引是项目知识总入口 |
|
||||
| [rules/10-架构说明.md](../../../../rules/10-架构说明.md) | 编辑器工具层的架构说明 |
|
||||
| [rules/30-模块登记规则.md](../../../../rules/30-模块登记规则.md) | 模块登记规则定义分类和状态口径 |
|
||||
| [编辑器工具入口](../README.md) | 编辑器工具模块入口 |
|
||||
| [MCP 使用规则](CrystalBattle_Codex_Unity_MCP使用规则.md) | 具体调用规范 |
|
||||
| [MCP Server README](../../../../Tools/CodexUnityMcp/README.md) | 安装和实现 |
|
||||
| [模块索引](../../../模块索引.md) | 模块状态 |
|
||||
| [工作流清单](../../../../rules/40-工作流清单.md) | Unity 自动化验证步骤 |
|
||||
|
||||
@@ -1,61 +1,36 @@
|
||||
# 编辑器工具
|
||||
|
||||
## 分类
|
||||
|
||||
- 编辑器工具
|
||||
|
||||
## 目的
|
||||
|
||||
汇总 Unity Editor 内使用的 StrayFog 相关编辑器扩展和项目编辑器资源。
|
||||
|
||||
---
|
||||
|
||||
## SF Editor
|
||||
|
||||
- **路径**:`Assets/StrayFog/Editor/`
|
||||
- **程序集**:`SFEditor`
|
||||
- **职责**:
|
||||
- StrayFog 编辑器扩展
|
||||
- 打包、UGUI、SpriteAtlas、表格路径选择等编辑器工具
|
||||
- 路径:`Assets/StrayFog/Editor/`
|
||||
- 程序集:`SFEditor`
|
||||
- 职责:CopyToX、AssetBundle、SpriteAtlas、配置生成和 StrayFog Editor 窗口。
|
||||
|
||||
---
|
||||
`Assets/StrayFog/Editor/CopyToX` 保存生成运行时代码的真实源文件。生成后的 GameHF/GameGeneral 目标目录禁止手改。
|
||||
|
||||
## Project Editor Assets
|
||||
|
||||
- **路径**:`Assets/Editor/`
|
||||
- **职责**:
|
||||
- 项目编辑器资源与脚本
|
||||
- 引导菜单、编辑器插件
|
||||
|
||||
---
|
||||
- 路径:目标项目 `Assets/Editor/`
|
||||
- 职责:项目级 Editor 菜单、构建辅助、UI 转换和 Unity MCP Bridge。
|
||||
|
||||
## 使用规则
|
||||
|
||||
- 编辑器工具可以读取/生成核心运行时代码,但运行时代码不要反向依赖 Editor 程序集。
|
||||
- 新增 Editor 工具时,优先在 `Assets/StrayFog/Editor/` 或 `Assets/Editor/` 下按功能分类存放。
|
||||
|
||||
---
|
||||
|
||||
## 相关模块
|
||||
|
||||
- [通用框架](../通用框架/README.md)
|
||||
- [资源管理](../资源管理/README.md)
|
||||
- Unity Editor API 只在主线程执行。
|
||||
- 运行时代码不得引用 Editor 程序集。
|
||||
- 生成器修改后同时验证输入配置、生成差异、目标程序集和 Unity Console。
|
||||
- 新增菜单时使用稳定路径;MCP 可调用菜单必须进入显式白名单。
|
||||
- 编辑器工具不能把机器绝对路径、个人目录或临时数据目录写成通用规则。
|
||||
|
||||
## 子文档
|
||||
|
||||
- [UI 拼接工具](UI拼接工具.md)
|
||||
- [MCP 工具](MCP工具/README.md)
|
||||
|
||||
---
|
||||
|
||||
## 文档关联
|
||||
|
||||
> 当本文档发生变更时,应同步检查以下关联文档,避免信息不一致。
|
||||
|
||||
| 文档 | 关联原因 |
|
||||
|---|---|
|
||||
| [modules/模块索引.md](../../模块索引.md) | 模块索引是项目知识总入口 |
|
||||
| [modules/frameworks/编辑器工具/UI拼接工具.md](UI拼接工具.md) | UI 预制体 JSON 双向转换工具 |
|
||||
| [modules/frameworks/编辑器工具/MCP工具/README.md](MCP工具/README.md) | Codex ↔ Unity MCP 工具 |
|
||||
| [rules/10-架构说明.md](../../../rules/10-架构说明.md) | 编辑器工具层的架构说明 |
|
||||
| [rules/30-模块登记规则.md](../../../rules/30-模块登记规则.md) | 模块登记规则定义分类和状态口径 |
|
||||
| [模块索引](../../模块索引.md) | 编辑器工具入口和状态 |
|
||||
| [资源管理](../资源管理/README.md) | AssetBundle 与分包生成 |
|
||||
| [架构说明](../../../rules/10-架构说明.md) | Editor 与运行时边界 |
|
||||
| [工作流清单](../../../rules/40-工作流清单.md) | 生成和验证流程 |
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using System.IO;
|
||||
|
||||
[InitializeOnLoad]
|
||||
public static class ExternalCommandListener
|
||||
{
|
||||
private static FileSystemWatcher watcher;
|
||||
private static string triggerFilePath;
|
||||
private static bool isInitialized = false;
|
||||
|
||||
static ExternalCommandListener()
|
||||
{
|
||||
EditorApplication.update += InitializeOnFirstUpdate;
|
||||
}
|
||||
|
||||
private static void InitializeOnFirstUpdate()
|
||||
{
|
||||
if (!isInitialized)
|
||||
{
|
||||
isInitialized = true;
|
||||
EditorApplication.update -= InitializeOnFirstUpdate;
|
||||
SetupFileWatcher();
|
||||
Debug.Log("ExternalCommandListener started");
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetupFileWatcher()
|
||||
{
|
||||
triggerFilePath = Path.Combine(Application.dataPath, "..", "Trigger_Command.txt");
|
||||
string watchFolder = Path.GetDirectoryName(triggerFilePath);
|
||||
|
||||
if (watcher != null) watcher.Dispose();
|
||||
|
||||
watcher = new FileSystemWatcher(watchFolder, "Trigger_Command.txt");
|
||||
watcher.NotifyFilter = NotifyFilters.CreationTime | NotifyFilters.LastWrite;
|
||||
watcher.Created += OnFileChanged;
|
||||
watcher.Changed += OnFileChanged;
|
||||
watcher.EnableRaisingEvents = true;
|
||||
}
|
||||
|
||||
private static void OnFileChanged(object sender, FileSystemEventArgs e)
|
||||
{
|
||||
if (e.ChangeType != WatcherChangeTypes.Created && e.ChangeType != WatcherChangeTypes.Changed)
|
||||
return;
|
||||
|
||||
EditorApplication.delayCall += ExecuteCommandFromFile;
|
||||
}
|
||||
|
||||
private static void ExecuteCommandFromFile()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!File.Exists(triggerFilePath)) return;
|
||||
|
||||
string content = File.ReadAllText(triggerFilePath).Trim();
|
||||
File.Delete(triggerFilePath);
|
||||
|
||||
ParseAndExecute(content);
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError("Execute failed: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ParseAndExecute(string content)
|
||||
{
|
||||
content = content.Trim().Trim('"', '\'');
|
||||
|
||||
string[] parts = content.Split(':');
|
||||
if (parts.Length == 0) return;
|
||||
|
||||
string command = parts[0].Trim();
|
||||
string[] args = parts.Length > 1 ? parts[1..] : new string[0];
|
||||
|
||||
ExecuteCommand(command, args);
|
||||
}
|
||||
|
||||
private static void ExecuteCommand(string command, string[] args)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case "ReadJson":
|
||||
ExecuteReadJson(args);
|
||||
break;
|
||||
case "GenerateUIPrefab":
|
||||
ExecuteGenerateUIPrefab(args);
|
||||
break;
|
||||
case "ExportPrefabToJson":
|
||||
ExecuteExportPrefabToJson(args);
|
||||
break;
|
||||
default:
|
||||
Debug.LogWarning("Unknown command: " + command);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExecuteReadJson(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var method = typeof(RemoteCommand).GetMethod("ReadJson",
|
||||
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static,
|
||||
null,
|
||||
new[] { typeof(string[]) },
|
||||
null);
|
||||
|
||||
if (method != null)
|
||||
{
|
||||
method.Invoke(null, new object[] { args });
|
||||
Debug.Log("Executed: ReadJson(" + string.Join(", ", args) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("RemoteCommand.ReadJson not found");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError("ReadJson failed: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExecuteGenerateUIPrefab(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var method = typeof(RemoteCommand).GetMethod("GenerateUIPrefab",
|
||||
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static,
|
||||
null,
|
||||
new[] { typeof(string[]) },
|
||||
null);
|
||||
|
||||
if (method != null)
|
||||
{
|
||||
method.Invoke(null, new object[] { args });
|
||||
Debug.Log("Executed: GenerateUIPrefab(" + string.Join(", ", args) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("RemoteCommand.GenerateUIPrefab not found");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError("GenerateUIPrefab failed: " + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ExecuteExportPrefabToJson(string[] args)
|
||||
{
|
||||
try
|
||||
{
|
||||
var method = typeof(RemoteCommand).GetMethod("ExportPrefabToJson",
|
||||
System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static,
|
||||
null,
|
||||
new[] { typeof(string[]) },
|
||||
null);
|
||||
|
||||
if (method != null)
|
||||
{
|
||||
method.Invoke(null, new object[] { args });
|
||||
Debug.Log("Executed: ExportPrefabToJson(" + string.Join(", ", args) + ")");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("RemoteCommand.ExportPrefabToJson not found");
|
||||
}
|
||||
}
|
||||
catch (System.Exception ex)
|
||||
{
|
||||
Debug.LogError("ExportPrefabToJson failed: " + ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 93f1f8f942aa53347a7e58bb4c561893
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,39 +0,0 @@
|
||||
public static class RemoteCommand
|
||||
{
|
||||
public static void ReadJson(string[] args)
|
||||
{
|
||||
SFP.Error("收到参数: " + string.Join(", ", args));
|
||||
}
|
||||
|
||||
public static void GenerateUIPrefab(string[] args)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
SFP.Error("GenerateUIPrefab: 需要提供JSON文件路径参数");
|
||||
return;
|
||||
}
|
||||
|
||||
string jsonPath = args[0];
|
||||
string prefabPath = args.Length > 1 ? args[1] : null;
|
||||
|
||||
SFP.Error("GenerateUIPrefab: 开始生成UI, JSON路径: " + jsonPath);
|
||||
|
||||
UIPrefabGenerator.GeneratePrefabFromJson(jsonPath, prefabPath);
|
||||
}
|
||||
|
||||
public static void ExportPrefabToJson(string[] args)
|
||||
{
|
||||
if (args.Length == 0)
|
||||
{
|
||||
SFP.Error("ExportPrefabToJson: 需要提供预制体文件路径参数");
|
||||
return;
|
||||
}
|
||||
|
||||
string prefabPath = args[0];
|
||||
string jsonPath = args.Length > 1 ? args[1] : null;
|
||||
|
||||
SFP.Error("ExportPrefabToJson: 开始导出JSON, 预制体路径: " + prefabPath);
|
||||
|
||||
UIPrefabToJson.ExportPrefabToJson(prefabPath, jsonPath);
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 359ded64689f3f64c87c561d88cead9d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -1,248 +1,104 @@
|
||||
# UI 拼接工具
|
||||
|
||||
## 概述
|
||||
## 目的
|
||||
|
||||
UI 拼接工具提供 JSON 配置与 Unity 预制体的双向转换,帮助 UI 相关人员通过 JSON 配置文件快速生成 UI 预制体,同时支持从现有预制体反向导出 JSON 用于版本控制或重新生成。
|
||||
UI 拼接工具通过 JSON 与 Unity Prefab 双向转换,帮助 Codex 和开发人员创建基础 UI 层级、检查现有 Prefab,并继续在 Unity 中完成业务绑定和视觉校对。
|
||||
|
||||
## 核心组件
|
||||
## 当前实现
|
||||
|
||||
| 组件 | 职责 | 文件路径 |
|
||||
|-----|------|---------|
|
||||
| **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` |
|
||||
| 组件 | 位置 | 职责 |
|
||||
|---|---|---|
|
||||
| `UIPrefabGenerator` | `Assets/Editor/Command/UIPrefabGenerator.cs` | 读取 UI JSON 并生成 Prefab |
|
||||
| `UIPrefabToJson` | `Assets/Editor/Command/UIPrefabToJson.cs` | 导出 Prefab 的层级和组件数据 |
|
||||
| Unity Bridge | `Assets/Editor/Command/CodexUnityEditorBridge.cs` | 在 Unity 主线程执行生成和导出命令 |
|
||||
| MCP Server | `UnityAI/Tools/CodexUnityMcp/` | 把 Unity Bridge 命令暴露给 Codex |
|
||||
|
||||
工具脚本在文档库中的位置(已并入编辑器工具模块):
|
||||
当前外部入口是 MCP Bridge,不使用文件监听或文本触发命令。
|
||||
|
||||
```
|
||||
modules/frameworks/编辑器工具/UI工具/
|
||||
├── ExternalCommandListener.cs # 外部命令监听器
|
||||
├── RemoteCommand.cs # 远程命令接口
|
||||
├── UIPrefabGenerator.cs # JSON 转预制体生成器
|
||||
└── UIPrefabToJson.cs # 预制体转 JSON 导出器
|
||||
```
|
||||
## 数据结构
|
||||
|
||||
## JSON 配置文件结构
|
||||
根节点使用 `UILayoutData`:
|
||||
|
||||
```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]
|
||||
}
|
||||
]
|
||||
"name": "ExampleWindow",
|
||||
"type": "Canvas",
|
||||
"layer": 5,
|
||||
"rectTransform": {
|
||||
"anchorMin": [0.5, 0.5],
|
||||
"anchorMax": [0.5, 0.5],
|
||||
"position": [0, 0, 0],
|
||||
"sizeDelta": [1080, 1920],
|
||||
"pivot": [0.5, 0.5],
|
||||
"localScale": [1, 1, 1],
|
||||
"localRotation": [0, 0, 0]
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
```
|
||||
|
||||
## 支持的 UI 元素类型
|
||||
子节点使用 `UIElementData`,可配置 `rectTransform`、`image`、`button`、`text`、`layoutGroup`、`scrollRect`、`toggle`、`slider`、`inputField`、`customComponents` 和递归 `children`。
|
||||
|
||||
| 类型 | 对应 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 |
|
||||
## 支持组件
|
||||
|
||||
## 外部命令触发机制
|
||||
- `Image` / `SFUI_Image`
|
||||
- `Button` / `SFUI_Button`
|
||||
- `TextMeshProUGUI` / `SFUI_TextMeshProUGUI`
|
||||
- `RectTransform`、`Canvas`、`CanvasScaler`、`GraphicRaycaster`
|
||||
- `ScrollRect` / `SFUI_ScrollRect`
|
||||
- `SFUI_Viewport`、`SFUI_Content`、`SFUI_ListViewItem`
|
||||
- `GridLayoutGroup`、`VerticalLayoutGroup`、`HorizontalLayoutGroup`
|
||||
- `Toggle` / `SFUI_Toggle`
|
||||
- `Slider` / `SFUI_Slider`
|
||||
- `InputField` / `SFUI_InputField`
|
||||
|
||||
### 触发方式
|
||||
资源字段使用 Unity Asset 路径,例如 `Assets/Game/...`,路径分隔符统一使用 `/`。
|
||||
|
||||
通过创建/修改 `Trigger_Command.txt` 文件触发 UI 生成:
|
||||
## MCP 调用
|
||||
|
||||
```
|
||||
GenerateUIPrefab:Assets/Editor/UI/BagWindow.json
|
||||
生成 Prefab:
|
||||
|
||||
```text
|
||||
unity_generate_ui_prefab(jsonPath, prefabPath)
|
||||
```
|
||||
|
||||
### 命令格式
|
||||
导出 Prefab:
|
||||
|
||||
```
|
||||
<命令名>:<参数1>:<参数2>:...
|
||||
```text
|
||||
unity_export_prefab_to_json(prefabPath, jsonPath)
|
||||
```
|
||||
|
||||
**支持的命令**:
|
||||
路径由当前任务明确传入,不规定固定测试目录或中间数据目录。目标正式窗口通常位于:
|
||||
|
||||
| 命令 | 参数 | 说明 |
|
||||
|-----|------|------|
|
||||
| **GenerateUIPrefab** | `jsonPath` [, `prefabPath`] | 根据 JSON 生成 UI 预制体 |
|
||||
| **ExportPrefabToJson** | `prefabPath` [, `jsonPath`] | 从预制体反向导出 JSON |
|
||||
| **ReadJson** | [参数列表] | 读取 JSON 配置(测试用) |
|
||||
|
||||
### 完整执行流程
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ 外部系统写入命令到 Trigger_Command.txt │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ ExternalCommandListener (FileSystemWatcher) 检测到文件变化 │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ 解析命令格式:GenerateUIPrefab:Assets/Editor/UI/BagWindow.json │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ 通过反射调用 RemoteCommand.GenerateUIPrefab(string[] args) │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ UIPrefabGenerator.GeneratePrefabFromJson(jsonPath, prefabPath) │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────────────────────────────────┐
|
||||
│ 生成预制体到指定路径:Assets/Game/GameHFResource/CN/UIWindows/... │
|
||||
└─────────────────────────────────────────────────────────────────────┘
|
||||
```text
|
||||
Assets/Game/GameHFResource/<语言>/UIWindows/<WindowName>/<WindowName>.prefab
|
||||
```
|
||||
|
||||
## 使用示例
|
||||
## 标准流程
|
||||
|
||||
### 方式一:外部命令触发
|
||||
1. 先读 [UI 界面拼接](../UI窗口系统/界面拼接.md) 和 [UI 开发指南](../UI窗口系统/开发指南.md)。
|
||||
2. 调用 `unity_health` 确认 Unity 项目和版本。
|
||||
3. 检查目标 Prefab、窗口脚本和可用资源。
|
||||
4. 生成基础 Prefab,或先导出现有 Prefab 再调整 JSON。
|
||||
5. 调用 `unity_refresh_assets`。
|
||||
6. 调用 `unity_get_console_logs` 检查 Error 和关键 Warning。
|
||||
7. 在 Unity 中检查层级、RectTransform、组件、资源引用和实际显示。
|
||||
|
||||
```bash
|
||||
# 正向:从 JSON 生成预制体
|
||||
echo "GenerateUIPrefab:Assets/Editor/UI/BagWindow.json" > "F:\JMNet\CrystalBattle_Client\Trigger_Command.txt"
|
||||
工具生成成功只表示 Prefab 文件已创建,不表示 UI 已完成。业务脚本、列表初始化、字体、图集、点击区域和视觉结果仍需验证。
|
||||
|
||||
# 反向:从预制体导出 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"
|
||||
);
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **路径格式**:JSON 中的资源路径使用 `/` 分隔符,且为 Unity 项目相对路径
|
||||
2. **资源引用**:确保 JSON 中引用的 Sprite、Font 等资源已存在于项目中
|
||||
3. **编码格式**:JSON 文件使用 UTF-8 编码
|
||||
4. **坐标系统**:使用 Unity RectTransform 的 anchorMin/anchorMax/position/sizeDelta 四元组
|
||||
5. **文件锁定**:生成前确保目标预制体文件未被其他进程占用
|
||||
|
||||
## 部署步骤
|
||||
|
||||
### 方法一:手动复制
|
||||
|
||||
1. 复制 `modules/frameworks/编辑器工具/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\modules\frameworks\编辑器工具\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
|
||||
```
|
||||
|
||||
### 部署检查项
|
||||
|
||||
| 检查项 | 要求 |
|
||||
|-------|------|
|
||||
| **目标路径** | 必须放置在 `Assets/Editor/Command/` 目录下 |
|
||||
| **文件完整性** | 必须包含所有 4 个 cs 文件及其 meta 文件 |
|
||||
| **Unity 版本** | 支持 Unity 2020 及以上版本 |
|
||||
| **依赖组件** | 需要导入 TextMeshPro 包 |
|
||||
|
||||
### 验证部署
|
||||
|
||||
部署完成后,在 Unity 编辑器中验证:
|
||||
|
||||
1. 打开 Unity 编辑器
|
||||
2. 检查菜单 `Tools > UI` 是否存在
|
||||
3. 检查菜单 `Tools > External` 是否存在
|
||||
4. 在 Console 窗口确认无编译错误
|
||||
|
||||
---
|
||||
|
||||
**版本**: v1.2
|
||||
**适用**: StrayFog 框架 UI 拼接开发人员
|
||||
|
||||
---
|
||||
- 覆盖已有 Prefab 前确认目标路径和现有内容。
|
||||
- 不通过 UI 生成工具批量删除、移动资源或执行构建发布。
|
||||
- Unity API 必须由 Bridge 排队到 Editor 主线程执行。
|
||||
- 生成后检查 Git 差异,避免无意义重序列化其他资源。
|
||||
- JSON 递归结构出现 serialization depth warning 时检查实际生成结果;新增 Error 必须处理。
|
||||
|
||||
## 文档关联
|
||||
|
||||
> 当本文档发生变更时,应同步检查以下关联文档,避免信息不一致。
|
||||
|
||||
| 文档 | 关联原因 |
|
||||
|---|---|
|
||||
| [编辑器工具入口](README.md) | 本文件是编辑器工具模块的子文档 |
|
||||
| [UI 窗口系统](../UI窗口系统/README.md) | UI 拼接工具服务于 UI 窗口系统 |
|
||||
| [UI 界面拼接设计指南](../UI窗口系统/界面拼接.md) | 设计指南说明 JSON 驱动的界面拼接原则 |
|
||||
| [modules/模块索引.md](../../模块索引.md) | 模块索引是项目知识总入口 |
|
||||
| [rules/10-架构说明.md](../../../rules/10-架构说明.md) | 架构说明定义编辑器工具层与运行时层边界 |
|
||||
| [rules/20-开发规则.md](../../../rules/20-开发规则.md) | 编辑器工具开发规则互相引用 |
|
||||
| [rules/30-模块登记规则.md](../../../rules/30-模块登记规则.md) | 模块登记规则定义分类和状态口径 |
|
||||
| [编辑器工具入口](README.md) | 编辑器工具模块入口 |
|
||||
| [UI 窗口系统](../UI窗口系统/README.md) | 窗口框架和资源路径 |
|
||||
| [UI 界面拼接](../UI窗口系统/界面拼接.md) | 视觉与 Prefab 流程 |
|
||||
| [MCP 使用规则](MCP工具/CrystalBattle_Codex_Unity_MCP使用规则.md) | Codex 调用和安全边界 |
|
||||
|
||||
Reference in New Issue
Block a user