4.0 KiB
4.0 KiB
ModelTranslator Unity 菜单集成设计文档
日期:2026-07-15 状态:已确认 前置: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(每用户每机器)正合适,不进版本库。
执行流程
- 校验(点转换前):FBX 存在;blender.exe 存在;python 可用。 不满足给明确中文提示(如"未找到 python,请安装 Python 3 或在面板中指定路径")。
- 启动:
Process异步运行<python> Tools/ModelTranslator/model_translator.py "<fbx>" -o "Client/Assets/Res[/子目录]" --max-size N --blender "<exe>", 工作目录 = 仓库根。路径全部加引号(中文/空格安全)。 - 转换中:不阻塞编辑器;
EditorApplication.update轮询,stdout 实时追加到日志区; 提供"取消"按钮(kill 进程);"转换"按钮置灰防并发。 - 成功(退出码 0):
AssetDatabase.Refresh()→PingObject选中Assets/Res/[子目录/]<模型名>/;日志区显示 CLI 的材质/警告报告。 - 失败(非零退出码):日志区显示 stdout+stderr 尾部,
DisplayDialog弹错误提示。 - 重复转换:CLI 复用已有
.meta的 GUID 直接覆盖,场景引用不丢(既有机制,无需处理)。
边界与错误处理
- 窗口关闭时进程还在跑 → kill
- stdout/stderr 用 UTF-8 读取(CLI 输出中文)
Assets/Res不存在时由 CLI 的os.makedirs自动创建,无需预建- 输出子目录做合法性清洗:剔除
..、绝对路径,只允许 Res 下的相对子路径
测试(手动验证清单)
C# 编辑器脚本无自动化测试框架,按清单手动验证:
- 正常转换
Tools/ModelTranslator/src/well.fbx→Assets/Res/well/出现且模型材质正确 - FBX 路径不存在 / blender 路径错 → 明确报错,不启动进程
- 转换中取消 → 进程被 kill,按钮恢复
- 同一模型二次转换 → GUID 不变(场景中已摆放的实例不丢材质)
- 输出子目录填
Scene/props→ 结果在Assets/Res/Scene/props/<模型名>/ - 关闭窗口再打开 → 参数记住上次的值
现有 Python 测试不受影响(CLI 未改)。