86 lines
4.0 KiB
Markdown
86 lines
4.0 KiB
Markdown
# ModelTranslator Unity 菜单集成设计文档
|
||
|
||
日期:2026-07-15
|
||
状态:已确认
|
||
前置:[2026-07-15-model-translator-design.md](2026-07-15-model-translator-design.md)(CLI 工具本体)
|
||
|
||
## 目标
|
||
|
||
在 Unity 编辑器中提供菜单入口,选择工程外的原始 FBX、设置参数(持久化保存)、
|
||
点击确认即调用 `Tools/ModelTranslator/model_translator.py` 转换,
|
||
结果输出到 `Client/Assets/Res/[子目录/]<模型名>/` 并自动刷新、选中。
|
||
|
||
CLI 本体**零改动**(`-o` 输出根目录 + 自动建 `<模型名>/` 子目录的既有行为正好满足需求)。
|
||
|
||
## 文件
|
||
|
||
```
|
||
Client/Assets/Editor/ModelTranslatorMenu.cs # 唯一新增文件
|
||
```
|
||
|
||
- `namespace XGame.Editor`,跟随 `MiniGamePublishMenu.cs` 的既有模式
|
||
- 菜单项:`XWorld/模型转换(XPbr)`,priority 803
|
||
|
||
## 窗口布局
|
||
|
||
```
|
||
┌─ 模型转换(XPbr) ────────────────┐
|
||
│ FBX 文件 [D:\...\well.fbx] [选择…] ← EditorUtility.OpenFilePanel,可选工程外文件
|
||
│ 贴图最大尺寸 [2048 ▼] ← 512/1024/2048/4096
|
||
│ 输出子目录 Assets/Res/[______] ← 留空 = 直接放 Res/<模型名>
|
||
│ Blender [D:\tools\...\blender.exe] [选择…]
|
||
│ Python [python] [选择…] ← 默认用 PATH 里的 python
|
||
│ ──────────────────────────
|
||
│ [ 转换 ] ← 校验不过/转换中 置灰
|
||
│ (转换日志/警告滚动区,等宽字体)
|
||
└────────────────────────────┘
|
||
```
|
||
|
||
## 参数持久化
|
||
|
||
`EditorPrefs`,key 前缀 `XWorld.ModelTranslator.*`:
|
||
|
||
| key | 默认值 |
|
||
|---|---|
|
||
| `maxSize` | 2048 |
|
||
| `outSubDir` | ""(直接放 Res 下) |
|
||
| `blenderPath` | `D:\tools\blender-5.0.0-windows-x64\blender.exe` |
|
||
| `pythonPath` | `python` |
|
||
| `lastFbxDir` | 上次选文件的目录(文件对话框起始位置) |
|
||
|
||
Blender/Python 路径每台机器不同,EditorPrefs(每用户每机器)正合适,不进版本库。
|
||
|
||
## 执行流程
|
||
|
||
1. **校验**(点转换前):FBX 存在;blender.exe 存在;python 可用。
|
||
不满足给明确中文提示(如"未找到 python,请安装 Python 3 或在面板中指定路径")。
|
||
2. **启动**:`Process` 异步运行
|
||
`<python> Tools/ModelTranslator/model_translator.py "<fbx>" -o "Client/Assets/Res[/子目录]" --max-size N --blender "<exe>"`,
|
||
工作目录 = 仓库根。路径全部加引号(中文/空格安全)。
|
||
3. **转换中**:不阻塞编辑器;`EditorApplication.update` 轮询,stdout 实时追加到日志区;
|
||
提供"取消"按钮(kill 进程);"转换"按钮置灰防并发。
|
||
4. **成功**(退出码 0):`AssetDatabase.Refresh()` → `PingObject` 选中
|
||
`Assets/Res/[子目录/]<模型名>/`;日志区显示 CLI 的材质/警告报告。
|
||
5. **失败**(非零退出码):日志区显示 stdout+stderr 尾部,`DisplayDialog` 弹错误提示。
|
||
6. **重复转换**:CLI 复用已有 `.meta` 的 GUID 直接覆盖,场景引用不丢(既有机制,无需处理)。
|
||
|
||
## 边界与错误处理
|
||
|
||
- 窗口关闭时进程还在跑 → kill
|
||
- stdout/stderr 用 UTF-8 读取(CLI 输出中文)
|
||
- `Assets/Res` 不存在时由 CLI 的 `os.makedirs` 自动创建,无需预建
|
||
- 输出子目录做合法性清洗:剔除 `..`、绝对路径,只允许 Res 下的相对子路径
|
||
|
||
## 测试(手动验证清单)
|
||
|
||
C# 编辑器脚本无自动化测试框架,按清单手动验证:
|
||
|
||
1. 正常转换 `Tools/ModelTranslator/src/well.fbx` → `Assets/Res/well/` 出现且模型材质正确
|
||
2. FBX 路径不存在 / blender 路径错 → 明确报错,不启动进程
|
||
3. 转换中取消 → 进程被 kill,按钮恢复
|
||
4. 同一模型二次转换 → GUID 不变(场景中已摆放的实例不丢材质)
|
||
5. 输出子目录填 `Scene/props` → 结果在 `Assets/Res/Scene/props/<模型名>/`
|
||
6. 关闭窗口再打开 → 参数记住上次的值
|
||
|
||
现有 Python 测试不受影响(CLI 未改)。
|