780 lines
20 KiB
Markdown
780 lines
20 KiB
Markdown
|
|
# Unity 风格模型导入与 Model 资产架构重构计划
|
|||
|
|
|
|||
|
|
日期:2026-04-10
|
|||
|
|
|
|||
|
|
## 1. 文档定位
|
|||
|
|
|
|||
|
|
这份计划覆盖 XCEngine 现阶段外部模型资源导入链路的结构性重构,目标不是“再给 `MeshLoader` 多加几个扩展名”,而是把模型资源正式提升为接近 Unity 的 `ModelImporter + ModelAsset` 工作流。
|
|||
|
|
|
|||
|
|
本计划默认遵循以下战略判断:
|
|||
|
|
|
|||
|
|
1. 当前工程已经具备基于 `Assimp` 的基础静态模型读取能力,`.obj/.fbx/.gltf/.glb/.dae/.stl` 都能进入导入链。
|
|||
|
|
2. 当前主资源仍然是 `Mesh`,这导致导入时会把大量上层语义压扁到静态网格层。
|
|||
|
|
3. 如果要走 Unity 风格,后续继续在 `Mesh` 主资产上堆功能会越来越别扭,必须先补一层真正的 `Model` 资产。
|
|||
|
|
4. 骨骼动画不是本轮主目标,但本轮的数据结构和 artifact 设计必须为它预留正式扩展位。
|
|||
|
|
|
|||
|
|
本轮计划的本质是:
|
|||
|
|
|
|||
|
|
1. 把“source model import”和“runtime mesh load”拆开。
|
|||
|
|
2. 把“外部模型文件的主资产类型”从 `Mesh` 提升到 `Model`。
|
|||
|
|
3. 把 `.obj/.fbx/...` 的导入体验统一到一条 `ModelImporter` 主链上。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 2. 当前状态判断
|
|||
|
|
|
|||
|
|
基于当前代码结构,可以确认已有能力与缺口如下。
|
|||
|
|
|
|||
|
|
### 2.1 已有能力
|
|||
|
|
|
|||
|
|
1. `MeshLoader` 已通过 `Assimp` 支持 `.fbx/.obj/.gltf/.glb/.dae/.stl/.xcmesh`。
|
|||
|
|
2. `AssetDatabase` 已将 `.obj/.fbx/.gltf/.glb/.dae/.stl` 识别为 `ModelImporter`。
|
|||
|
|
3. 编辑器 `MeshFilter` 的资源选择 UI 已允许 `.fbx/.obj/.gltf/.glb`。
|
|||
|
|
4. 工程已接入 `assimp-vc143-mt.dll`,说明构建链和基础运行依赖已经建立。
|
|||
|
|
5. 当前 artifact 管线已经具备 `xcmesh/xcmat/xctex` 的写入与回读能力。
|
|||
|
|
|
|||
|
|
### 2.2 当前核心问题
|
|||
|
|
|
|||
|
|
1. `ModelImporter` 的主资源类型实际上仍然是 `Mesh`,并不是真正的 `Model`。
|
|||
|
|
2. 导入时递归遍历 Assimp node,但会把 node transform 烘进顶点,原始层级、局部变换、pivot 语义丢失。
|
|||
|
|
3. `Mesh` 顶点结构当前仍是静态网格视角,只覆盖 `position/normal/tangent/bitangent/uv0`。
|
|||
|
|
4. `MeshImportSettings` 中虽然已经出现 `ImportSkinning / ImportAnimations / ImportCameras / ImportLights` 等标志,但没有形成对应的正式数据通路。
|
|||
|
|
5. `.meta` 当前只写 importer 名称和版本,没有形成 Unity 风格的模型导入设置持久化。
|
|||
|
|
6. 测试主要覆盖 `obj` 路径,针对真实 `fbx` fixture 的链路验证明显不足。
|
|||
|
|
7. 拖模型进场景时,现有工作流更接近“给一个 `GameObject` 绑定单个 `Mesh`”,而不是实例化一棵模型层级。
|
|||
|
|
|
|||
|
|
### 2.3 当前阶段最重要的判断
|
|||
|
|
|
|||
|
|
当前问题不在于“FBX 能不能读进来”,而在于“读进来以后是被当成 `Mesh` 还是被当成 `Model`”。
|
|||
|
|
|
|||
|
|
如果继续让外部模型文件直接产出主 `Mesh`:
|
|||
|
|
|
|||
|
|
1. `OBJ` 还能勉强成立。
|
|||
|
|
2. `FBX` 会不断丢失层级、pivot、子节点、多部件组织等上层语义。
|
|||
|
|
3. 后续无论做子资产展开、模型 prefab 化、骨骼动画还是稳定 reimport,都会越来越难。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 3. 目标架构决策
|
|||
|
|
|
|||
|
|
### 3.1 总体决策
|
|||
|
|
|
|||
|
|
长期目标不是:
|
|||
|
|
|
|||
|
|
1. `OBJ -> Mesh`
|
|||
|
|
2. `FBX -> Model`
|
|||
|
|
|
|||
|
|
而是统一到:
|
|||
|
|
|
|||
|
|
1. 外部模型格式统一进入 `ModelImporter`
|
|||
|
|
2. `ModelImporter` 的主产物统一是 `Model`
|
|||
|
|
3. `Model` 内部再引用一个或多个 `Mesh/Material/Texture`
|
|||
|
|
|
|||
|
|
即:
|
|||
|
|
|
|||
|
|
1. `.obj -> 简化 Model`
|
|||
|
|
2. `.fbx -> 完整 Model`
|
|||
|
|
3. `.gltf/.glb/... -> 同样走 Model 主链`
|
|||
|
|
|
|||
|
|
这样做的好处是:
|
|||
|
|
|
|||
|
|
1. 资源系统主线统一。
|
|||
|
|
2. 编辑器工作流统一。
|
|||
|
|
3. 子资产稳定引用机制统一。
|
|||
|
|
4. 骨骼、动画、blend shape、嵌入纹理等后续扩展都有正式落点。
|
|||
|
|
|
|||
|
|
### 3.2 `Mesh` 与 `Model` 的职责边界
|
|||
|
|
|
|||
|
|
`Mesh` 只回答一件事:
|
|||
|
|
|
|||
|
|
1. 这个表面怎么画。
|
|||
|
|
|
|||
|
|
它应该承载:
|
|||
|
|
|
|||
|
|
1. 顶点数据
|
|||
|
|
2. 索引数据
|
|||
|
|
3. section
|
|||
|
|
4. bounds
|
|||
|
|
5. 材质槽位数量与 section-material 映射
|
|||
|
|
|
|||
|
|
`Model` 回答另一件事:
|
|||
|
|
|
|||
|
|
1. 这个资源整体怎么组织。
|
|||
|
|
|
|||
|
|
它应该承载:
|
|||
|
|
|
|||
|
|
1. 节点层级
|
|||
|
|
2. 节点局部 TRS
|
|||
|
|
3. 节点名字与路径
|
|||
|
|
4. 节点绑定的 mesh 引用
|
|||
|
|
5. 每个 mesh 节点的材质槽绑定
|
|||
|
|
6. 根节点信息
|
|||
|
|
7. 导入元数据
|
|||
|
|
8. 未来的 skeleton / animation / blend shape 扩展位
|
|||
|
|
|
|||
|
|
### 3.3 运行时链路的长期形态
|
|||
|
|
|
|||
|
|
长期上应当形成三层:
|
|||
|
|
|
|||
|
|
1. `ModelImporter`
|
|||
|
|
负责 source file -> artifact graph
|
|||
|
|
2. `ModelLoader`
|
|||
|
|
负责读取 `xcmodel`
|
|||
|
|
3. `MeshLoader`
|
|||
|
|
负责读取 `xcmesh`
|
|||
|
|
|
|||
|
|
其中:
|
|||
|
|
|
|||
|
|
1. `MeshLoader` 不再承担完整 source scene import 的主责任。
|
|||
|
|
2. `MeshLoader` 更适合退化成“运行时 mesh artifact 加载器 + builtin mesh loader”。
|
|||
|
|
3. 所有 source model 的正式导入都应该通过 `ModelImporter` 的专用实现完成。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 4. 本轮范围与明确不做的内容
|
|||
|
|
|
|||
|
|
### 4.1 本轮必须完成
|
|||
|
|
|
|||
|
|
1. `Model` 资源类型与 `xcmodel` artifact。
|
|||
|
|
2. 统一的 `ModelImporter` 主链。
|
|||
|
|
3. `.meta` 中的 Model Import Settings 持久化。
|
|||
|
|
4. 保留层级的静态模型导入。
|
|||
|
|
5. 场景中实例化模型层级的工作流。
|
|||
|
|
6. 子资产与稳定 `LocalID` 规则。
|
|||
|
|
7. 编辑器中的模型导入设置 Inspector。
|
|||
|
|
8. `OBJ/FBX` 静态模型的正式测试闭环。
|
|||
|
|
|
|||
|
|
### 4.2 本轮暂不做
|
|||
|
|
|
|||
|
|
1. `SkinnedMeshRenderer` 正式渲染链。
|
|||
|
|
2. 骨骼矩阵上传与 GPU skinning。
|
|||
|
|
3. 动画 clip runtime 播放系统。
|
|||
|
|
4. blend shape runtime。
|
|||
|
|
5. 完整相机/灯光从 `FBX` 到 scene 的自动生成。
|
|||
|
|
6. 模型子资产在 Project 面板中的完整可展开 UI。
|
|||
|
|
|
|||
|
|
### 4.3 本轮只预留不落地的内容
|
|||
|
|
|
|||
|
|
1. `Skeleton` 资源类型接口
|
|||
|
|
2. `AnimationClip` 资源类型接口
|
|||
|
|
3. `Model` 中 skeleton/animation 的 artifact 扩展位
|
|||
|
|
4. skinning/blend shape 所需的稳定 source 标识规则
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 5. 目标数据结构设计
|
|||
|
|
|
|||
|
|
### 5.1 新增资源类型
|
|||
|
|
|
|||
|
|
建议在 `ResourceType` 中正式新增:
|
|||
|
|
|
|||
|
|
1. `Model`
|
|||
|
|
|
|||
|
|
同时保留已有:
|
|||
|
|
|
|||
|
|
1. `Mesh`
|
|||
|
|
2. `Material`
|
|||
|
|
3. `Texture`
|
|||
|
|
4. `AnimationClip`
|
|||
|
|
5. `Skeleton`
|
|||
|
|
|
|||
|
|
即使 `AnimationClip/Skeleton` 本轮不真正导出,也应在设计上与 `Model` 并列存在。
|
|||
|
|
|
|||
|
|
### 5.2 `Model` 资源结构建议
|
|||
|
|
|
|||
|
|
`Model` 至少包含以下结构:
|
|||
|
|
|
|||
|
|
1. `ModelNode`
|
|||
|
|
- `name`
|
|||
|
|
- `parentIndex`
|
|||
|
|
- `firstChildIndex / childCount` 或 child index array
|
|||
|
|
- `localPosition`
|
|||
|
|
- `localRotation`
|
|||
|
|
- `localScale`
|
|||
|
|
- `meshBindingStart`
|
|||
|
|
- `meshBindingCount`
|
|||
|
|
2. `ModelMeshBinding`
|
|||
|
|
- `meshLocalID`
|
|||
|
|
- `materialBindingStart`
|
|||
|
|
- `materialBindingCount`
|
|||
|
|
3. `ModelMaterialBinding`
|
|||
|
|
- `slotIndex`
|
|||
|
|
- `materialLocalID`
|
|||
|
|
4. `ModelImportMetadata`
|
|||
|
|
- importer version
|
|||
|
|
- source file signature
|
|||
|
|
- import settings snapshot
|
|||
|
|
|
|||
|
|
### 5.3 `Mesh` 资源职责调整
|
|||
|
|
|
|||
|
|
`Mesh` 继续作为低层渲染资源保留,但职责要收紧:
|
|||
|
|
|
|||
|
|
1. 不再把 source model file 当成它的长期主输入。
|
|||
|
|
2. 主要负责:
|
|||
|
|
- `xcmesh`
|
|||
|
|
- builtin mesh
|
|||
|
|
3. source format 直接读取只作为过渡能力,后续应弱化。
|
|||
|
|
|
|||
|
|
### 5.4 `Model` artifact 文件布局
|
|||
|
|
|
|||
|
|
建议 artifact 目录布局统一为:
|
|||
|
|
|
|||
|
|
1. `main.xcmodel`
|
|||
|
|
2. `mesh_0.xcmesh`
|
|||
|
|
3. `mesh_1.xcmesh`
|
|||
|
|
4. `material_0.xcmat`
|
|||
|
|
5. `material_1.xcmat`
|
|||
|
|
6. `texture_0.xctex`
|
|||
|
|
7. `texture_1.xctex`
|
|||
|
|
8. 未来可扩展:
|
|||
|
|
- `skeleton_0.xcskel`
|
|||
|
|
- `anim_0.xcanim`
|
|||
|
|
|
|||
|
|
### 5.5 `LocalID` 稳定规则
|
|||
|
|
|
|||
|
|
这是整个 Unity 风格方案里最关键的一部分。
|
|||
|
|
|
|||
|
|
不能简单使用“导入顺序下标”作为长期稳定标识。应当引入基于源语义的稳定 `LocalID` 生成策略:
|
|||
|
|
|
|||
|
|
1. Node:基于节点路径生成
|
|||
|
|
2. Mesh:基于节点路径 + mesh name + source mesh index 生成
|
|||
|
|
3. Material:基于 material name + source material index 生成
|
|||
|
|
4. Texture:基于 source texture path 或 embedded texture key 生成
|
|||
|
|
5. 后续骨骼/动画:基于骨骼名、clip 名、source index 生成
|
|||
|
|
|
|||
|
|
目标是:
|
|||
|
|
|
|||
|
|
1. 同一个模型在普通 reimport 后,子资产 `LocalID` 不变。
|
|||
|
|
2. 场景/prefab/材质槽引用不因为 artifact 目录变化而失效。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 6. 导入链路重构方案
|
|||
|
|
|
|||
|
|
### 6.1 引入专用 source importer
|
|||
|
|
|
|||
|
|
建议新增专用模块,例如:
|
|||
|
|
|
|||
|
|
1. `AssimpModelImporter`
|
|||
|
|
|
|||
|
|
它的职责是:
|
|||
|
|
|
|||
|
|
1. 读取 `.obj/.fbx/.gltf/.glb/...`
|
|||
|
|
2. 产出统一中间结构 `ImportedModel`
|
|||
|
|
3. 再由 artifact writer 写出 `xcmodel/xcmesh/xcmat/xctex`
|
|||
|
|
|
|||
|
|
不建议继续把这部分主逻辑堆在 `MeshLoader` 内部。
|
|||
|
|
|
|||
|
|
### 6.2 导入中间结构
|
|||
|
|
|
|||
|
|
建议先建立 importer 内部中间结构:
|
|||
|
|
|
|||
|
|
1. `ImportedModel`
|
|||
|
|
2. `ImportedNode`
|
|||
|
|
3. `ImportedMesh`
|
|||
|
|
4. `ImportedMaterial`
|
|||
|
|
5. `ImportedTexture`
|
|||
|
|
|
|||
|
|
这样可以把:
|
|||
|
|
|
|||
|
|
1. Assimp scene 读取
|
|||
|
|
2. 引擎内部资源表示
|
|||
|
|
3. artifact 写出
|
|||
|
|
|
|||
|
|
三者解耦。
|
|||
|
|
|
|||
|
|
### 6.3 节点与变换处理原则
|
|||
|
|
|
|||
|
|
这是与当前实现最大的差异之一。
|
|||
|
|
|
|||
|
|
当前做法是把 `node` 变换乘到顶点上,再把所有几何收进同一个 `Mesh`。本轮要改成:
|
|||
|
|
|
|||
|
|
1. Mesh 顶点保持在 mesh local space
|
|||
|
|
2. Node local transform 单独存进 `Model`
|
|||
|
|
3. Scene 实例化时再把 node local transform 还原到 `GameObject`
|
|||
|
|
|
|||
|
|
只有这样才能保留:
|
|||
|
|
|
|||
|
|
1. 层级
|
|||
|
|
2. pivot
|
|||
|
|
3. 本地 TRS
|
|||
|
|
4. 后续动画骨骼的基础结构
|
|||
|
|
|
|||
|
|
### 6.4 轴系与缩放的处理原则
|
|||
|
|
|
|||
|
|
建议明确以下规则:
|
|||
|
|
|
|||
|
|
1. 轴系转换属于导入标准化步骤,但不能以“摧毁原始层级”为代价。
|
|||
|
|
2. 全局 import scale 应优先体现在 root 侧或 mesh 侧的单一标准化策略中,不要 mesh 与 node 两边重复施加。
|
|||
|
|
3. 一旦规则确定,要在 `ModelImportSettings` 中固定,并进入 `metaHash`。
|
|||
|
|
|
|||
|
|
本轮必须把“坐标转换在哪里做、缩放在哪里做”写成正式约束,而不是散落在 loader 里。
|
|||
|
|
|
|||
|
|
### 6.5 `OBJ` 的导入策略
|
|||
|
|
|
|||
|
|
`OBJ` 仍然统一走 `ModelImporter`,但导入结果通常是一个简化模型:
|
|||
|
|
|
|||
|
|
1. 一个 root node
|
|||
|
|
2. 一个或少量 mesh node
|
|||
|
|
3. 少量 material bindings
|
|||
|
|
|
|||
|
|
即:
|
|||
|
|
|
|||
|
|
1. `OBJ` 不是继续作为架构特例保留在 `Mesh` 主链外面
|
|||
|
|
2. 它只是“语义很简单的 model source”
|
|||
|
|
|
|||
|
|
### 6.6 `FBX` 的导入策略
|
|||
|
|
|
|||
|
|
`FBX` 则要保留完整静态结构:
|
|||
|
|
|
|||
|
|
1. node hierarchy
|
|||
|
|
2. local transform
|
|||
|
|
3. mesh attachments
|
|||
|
|
4. material slots
|
|||
|
|
5. embedded/external textures
|
|||
|
|
6. 后续可扩展 skeleton/animation metadata
|
|||
|
|
|
|||
|
|
即使本轮不做动画,也不应该再把 `FBX` 烘成单个主 `Mesh`。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 7. AssetDatabase 与 ArtifactDatabase 改造计划
|
|||
|
|
|
|||
|
|
### 7.1 主资产类型调整
|
|||
|
|
|
|||
|
|
当前 `ModelImporter` 的主资产仍是 `Mesh`。本轮要改成:
|
|||
|
|
|
|||
|
|
1. `ModelImporter` 主资产类型为 `Model`
|
|||
|
|
2. `mainLocalID` 指向 `Model` 主资产
|
|||
|
|
3. `Mesh/Material/Texture` 成为其子资产
|
|||
|
|
|
|||
|
|
### 7.2 `EnsureArtifact` 语义调整
|
|||
|
|
|
|||
|
|
对 `Assets/Models/robot.fbx` 执行 `EnsureArtifact(..., ResourceType::Model)` 时:
|
|||
|
|
|
|||
|
|
1. 返回主 `xcmodel`
|
|||
|
|
2. 内部子资产可通过 `AssetRef(assetGuid, localID, resourceType)` 访问
|
|||
|
|
|
|||
|
|
若后续有需要,`MeshFilter` 等组件可直接引用某个 `Mesh` 子资产,而不是引用主 `Model`。
|
|||
|
|
|
|||
|
|
### 7.3 依赖追踪调整
|
|||
|
|
|
|||
|
|
当前依赖追踪对 `obj -> mtl -> texture` 已有基础覆盖,但本轮要升级成通用模型依赖追踪:
|
|||
|
|
|
|||
|
|
1. source model file
|
|||
|
|
2. 外部纹理
|
|||
|
|
3. embedded texture 的派生 key
|
|||
|
|
4. 导入设置 meta
|
|||
|
|
5. future:外部 animation source / skeleton source
|
|||
|
|
|
|||
|
|
目标是:
|
|||
|
|
|
|||
|
|
1. 改 texture 会触发模型 reimport
|
|||
|
|
2. 改 importer settings 会触发模型 reimport
|
|||
|
|
3. 子资产 artifact 会稳定重建
|
|||
|
|
|
|||
|
|
### 7.4 资源查询接口调整
|
|||
|
|
|
|||
|
|
建议新增或调整:
|
|||
|
|
|
|||
|
|
1. `TryGetAssetRef(path, ResourceType::Model, ...)`
|
|||
|
|
2. `TryGetSubAssetRef(path, subAssetKey or localID, ResourceType::Mesh, ...)`
|
|||
|
|
3. `TryGetPrimaryAssetPath(guid, ...)` 对 `Model` 继续保持主资产语义
|
|||
|
|
|
|||
|
|
同时要保证:
|
|||
|
|
|
|||
|
|
1. 主 `Model` 与子 `Mesh` 的引用路径语义清晰
|
|||
|
|
2. 编辑器与场景序列化知道自己引用的是主资产还是子资产
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 8. `.meta` 与导入设置计划
|
|||
|
|
|
|||
|
|
### 8.1 当前问题
|
|||
|
|
|
|||
|
|
当前 `.meta` 只有:
|
|||
|
|
|
|||
|
|
1. `guid`
|
|||
|
|
2. `folderAsset`
|
|||
|
|
3. `importer`
|
|||
|
|
4. `importerVersion`
|
|||
|
|
|
|||
|
|
这不足以支撑 Unity 风格模型工作流。
|
|||
|
|
|
|||
|
|
### 8.2 新增 `ModelImportSettings`
|
|||
|
|
|
|||
|
|
建议正式引入或升级为:
|
|||
|
|
|
|||
|
|
1. `ModelImportSettings`
|
|||
|
|
|
|||
|
|
至少包括:
|
|||
|
|
|
|||
|
|
1. `globalScale`
|
|||
|
|
2. `axisConversion`
|
|||
|
|
3. `flipUVs`
|
|||
|
|
4. `flipWindingOrder`
|
|||
|
|
5. `generateNormals`
|
|||
|
|
6. `generateTangents`
|
|||
|
|
7. `importMaterials`
|
|||
|
|
8. `extractEmbeddedTextures`
|
|||
|
|
9. `preserveHierarchy`
|
|||
|
|
10. `mergeStaticMeshes`
|
|||
|
|
11. 预留:
|
|||
|
|
- `importSkinning`
|
|||
|
|
- `importAnimations`
|
|||
|
|
- `importCameras`
|
|||
|
|
- `importLights`
|
|||
|
|
|
|||
|
|
### 8.3 `.meta` 持久化规则
|
|||
|
|
|
|||
|
|
应当把上述设置正式写入 `.meta`,并参与 `metaHash`。
|
|||
|
|
|
|||
|
|
目标是:
|
|||
|
|
|
|||
|
|
1. 切换 importer setting 后 artifact key 会变化
|
|||
|
|
2. `Reimport` 有明确语义
|
|||
|
|
3. Inspector 改完设置能稳定反映到导入结果
|
|||
|
|
|
|||
|
|
### 8.4 版本策略
|
|||
|
|
|
|||
|
|
建议:
|
|||
|
|
|
|||
|
|
1. `ModelImporter` 单独维护 importer version
|
|||
|
|
2. 当 `xcmodel` schema 或子资产布局变化时,显式提升版本号
|
|||
|
|
3. 不再使用“整个 AssetDatabase 共用一个笼统版本号”来覆盖全部导入器变化
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 9. 编辑器工作流计划
|
|||
|
|
|
|||
|
|
### 9.1 Project 面板语义
|
|||
|
|
|
|||
|
|
`.obj/.fbx/.gltf/.glb/...` 在 Project 面板中应统一显示为:
|
|||
|
|
|
|||
|
|
1. `Model`
|
|||
|
|
|
|||
|
|
而不是继续让用户默认把这些资源理解成“单个 mesh 文件”。
|
|||
|
|
|
|||
|
|
### 9.2 Model Importer Inspector
|
|||
|
|
|
|||
|
|
选中模型资源时,Inspector 需要出现真正的导入设置面板:
|
|||
|
|
|
|||
|
|
1. Import Settings
|
|||
|
|
2. Apply
|
|||
|
|
3. Revert
|
|||
|
|
4. Reimport
|
|||
|
|
|
|||
|
|
首批显示的设置至少包括:
|
|||
|
|
|
|||
|
|
1. Scale
|
|||
|
|
2. Axis Conversion
|
|||
|
|
3. Preserve Hierarchy
|
|||
|
|
4. Import Materials
|
|||
|
|
5. Generate Normals
|
|||
|
|
6. Generate Tangents
|
|||
|
|
7. Flip UVs
|
|||
|
|
|
|||
|
|
### 9.3 场景拖拽行为
|
|||
|
|
|
|||
|
|
把模型资源拖进场景时,不应只创建一个空物体加一个 `MeshFilter`。
|
|||
|
|
|
|||
|
|
推荐行为:
|
|||
|
|
|
|||
|
|
1. 读取 `Model`
|
|||
|
|
2. 生成对应 `GameObject` 树
|
|||
|
|
3. 按节点局部变换恢复 TRS
|
|||
|
|
4. 对带 mesh 的节点挂 `MeshFilter + MeshRenderer`
|
|||
|
|
5. 材质槽按 `Model` 内的绑定还原
|
|||
|
|
|
|||
|
|
这才接近 Unity 的“拖入模型得到层级实例”。
|
|||
|
|
|
|||
|
|
### 9.4 子资产访问
|
|||
|
|
|
|||
|
|
本轮不强制要求 Project 面板完整展开子资产树,但至少应保证:
|
|||
|
|
|
|||
|
|
1. `MeshFilter` 能引用模型产出的某个 `Mesh` 子资产
|
|||
|
|
2. 场景序列化后引用稳定
|
|||
|
|
3. 后续补 Project 子资产展开 UI 时不需要推倒重来
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 10. 场景实例化与运行时路径
|
|||
|
|
|
|||
|
|
### 10.1 不建议增加 `ModelComponent`
|
|||
|
|
|
|||
|
|
为了贴近 Unity,建议不要把“整个模型实例”抽成一个新的 `ModelComponent` 挂在单个对象上。
|
|||
|
|
|
|||
|
|
更合理的做法是:
|
|||
|
|
|
|||
|
|
1. `Model` 是资源
|
|||
|
|
2. “实例化模型”是一个 utility / service
|
|||
|
|
3. 实例化结果是 `GameObject` 层级
|
|||
|
|
|
|||
|
|
### 10.2 建议新增实例化工具层
|
|||
|
|
|
|||
|
|
可以新增例如:
|
|||
|
|
|
|||
|
|
1. `ModelInstantiationUtility`
|
|||
|
|
2. `InstantiateModelAsset(...)`
|
|||
|
|
|
|||
|
|
职责:
|
|||
|
|
|
|||
|
|
1. 根据 `Model` 创建场景层级
|
|||
|
|
2. 为每个节点恢复局部 TRS
|
|||
|
|
3. 绑定子 `Mesh`
|
|||
|
|
4. 绑定默认材质或导入材质
|
|||
|
|
|
|||
|
|
### 10.3 与现有渲染链的兼容策略
|
|||
|
|
|
|||
|
|
现有渲染链以 `MeshFilter + MeshRenderer` 为中心,这一层本轮不应推翻。
|
|||
|
|
|
|||
|
|
本轮应当:
|
|||
|
|
|
|||
|
|
1. 保持 runtime 渲染主链稳定
|
|||
|
|
2. 通过新的 `Model -> GameObject hierarchy` 实例化路径,把 `Model` 翻译回现有组件体系
|
|||
|
|
|
|||
|
|
这样风险最小,且后续加 `SkinnedMeshRenderer` 时也有自然落点。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 11. 测试与验证计划
|
|||
|
|
|
|||
|
|
### 11.1 Fixture 规划
|
|||
|
|
|
|||
|
|
必须新增真实模型 fixture,不再只停留在字符串层面的 `CanLoad("test.fbx")`。
|
|||
|
|
|
|||
|
|
建议至少准备:
|
|||
|
|
|
|||
|
|
1. `single_mesh_static.obj`
|
|||
|
|
2. `single_mesh_static.fbx`
|
|||
|
|
3. `multi_node_static.fbx`
|
|||
|
|
4. `multi_material_static.fbx`
|
|||
|
|
5. `embedded_texture_static.fbx`
|
|||
|
|
6. `external_texture_static.fbx`
|
|||
|
|
|
|||
|
|
### 11.2 Unit Test
|
|||
|
|
|
|||
|
|
建议新增或扩展:
|
|||
|
|
|
|||
|
|
1. `ModelLoader` 基础加载测试
|
|||
|
|
2. `ModelImportSettings` 持久化测试
|
|||
|
|
3. `ModelArtifact` 写入/回读测试
|
|||
|
|
4. `LocalID` 稳定性测试
|
|||
|
|
5. `AssetDatabase` 主资产/子资产引用测试
|
|||
|
|
|
|||
|
|
### 11.3 Integration Test
|
|||
|
|
|
|||
|
|
建议新增:
|
|||
|
|
|
|||
|
|
1. `FBX -> xcmodel -> scene instantiate` 集成测试
|
|||
|
|
2. reimport 后 `AssetRef` 稳定性测试
|
|||
|
|
3. 多节点模型实例化后层级与局部变换恢复测试
|
|||
|
|
4. 多材质槽绑定测试
|
|||
|
|
|
|||
|
|
### 11.4 Editor Test
|
|||
|
|
|
|||
|
|
建议补:
|
|||
|
|
|
|||
|
|
1. Project 面板模型类型识别
|
|||
|
|
2. Model Importer Inspector 设置编辑
|
|||
|
|
3. Apply/Reimport 行为
|
|||
|
|
4. 拖模型到场景生成层级
|
|||
|
|
|
|||
|
|
### 11.5 验收原则
|
|||
|
|
|
|||
|
|
本轮不能以“能读进一个 FBX 文件”作为完成标准。
|
|||
|
|
|
|||
|
|
必须同时满足:
|
|||
|
|
|
|||
|
|
1. artifact 正确
|
|||
|
|
2. hierarchy 正确
|
|||
|
|
3. reimport 稳定
|
|||
|
|
4. editor 工作流成立
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 12. 分阶段执行计划
|
|||
|
|
|
|||
|
|
### Phase 1:`Model` 资源与 artifact 基础设施落地
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
1. 新增 `ResourceType::Model`
|
|||
|
|
2. 新增 `Model` 类与 `ModelLoader`
|
|||
|
|
3. 新增 `xcmodel` artifact 格式
|
|||
|
|
|
|||
|
|
任务:
|
|||
|
|
|
|||
|
|
1. 设计 `ModelNode / ModelMeshBinding / ModelMaterialBinding`
|
|||
|
|
2. 在 `ArtifactFormats` 中定义 `ModelArtifactHeader`
|
|||
|
|
3. 实现 `WriteModelArtifactFile / LoadModelArtifact`
|
|||
|
|
4. 让 `ResourceManager` 注册 `ModelLoader`
|
|||
|
|
|
|||
|
|
验收标准:
|
|||
|
|
|
|||
|
|
1. `xcmodel` 能写出与读回
|
|||
|
|
2. `Model` 可被 `ResourceManager` 正式加载
|
|||
|
|
|
|||
|
|
### Phase 2:source import 主链从 `Mesh` 迁移到 `Model`
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
1. 建立 `AssimpModelImporter`
|
|||
|
|
2. 将 `.obj/.fbx/...` 的正式导入主链切换到 `Model`
|
|||
|
|
|
|||
|
|
任务:
|
|||
|
|
|
|||
|
|
1. 建立 `ImportedModel` 中间结构
|
|||
|
|
2. 从 Assimp scene 提取节点层级、局部 TRS、mesh、material、texture
|
|||
|
|
3. 停止在导入主链中把 node transform 烘平到单个主 mesh
|
|||
|
|
4. 输出 `main.xcmodel + sub assets`
|
|||
|
|
|
|||
|
|
验收标准:
|
|||
|
|
|
|||
|
|
1. `OBJ` 被导入成简化 `Model`
|
|||
|
|
2. `FBX` 被导入成保留 hierarchy 的 `Model`
|
|||
|
|
|
|||
|
|
### Phase 3:`AssetDatabase` 子资产与稳定 `LocalID`
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
1. 完成主资产/子资产语义
|
|||
|
|
2. 建立稳定 `LocalID` 规则
|
|||
|
|
|
|||
|
|
任务:
|
|||
|
|
|
|||
|
|
1. 修改 `ModelImporter` 的主资源类型
|
|||
|
|
2. 实现模型子资产 `AssetRef`
|
|||
|
|
3. 让 `EnsureArtifact`、`TryGetAssetRef`、序列化链路理解 `Model` 主资产与子 `Mesh`
|
|||
|
|
4. 建立 reimport 稳定性测试
|
|||
|
|
|
|||
|
|
验收标准:
|
|||
|
|
|
|||
|
|
1. reimport 后子资产引用不漂移
|
|||
|
|
2. 场景中的 mesh 引用可稳定恢复
|
|||
|
|
|
|||
|
|
### Phase 4:`.meta` 与 Model Import Settings 正式化
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
1. 让模型导入参数进入正式工作流
|
|||
|
|
|
|||
|
|
任务:
|
|||
|
|
|
|||
|
|
1. 定义 `ModelImportSettings`
|
|||
|
|
2. 把 settings 写入 `.meta`
|
|||
|
|
3. 调整 `metaHash`
|
|||
|
|
4. 保证 settings 变化触发 reimport
|
|||
|
|
|
|||
|
|
验收标准:
|
|||
|
|
|
|||
|
|
1. 改 scale/axis/material 等设置会稳定影响导入结果
|
|||
|
|
2. artifact key 与导入设置一致变化
|
|||
|
|
|
|||
|
|
### Phase 5:编辑器 Inspector 与场景实例化工作流
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
1. 建立 Unity 风格的模型资源使用体验
|
|||
|
|
|
|||
|
|
任务:
|
|||
|
|
|
|||
|
|
1. Project 面板统一把模型文件识别为 `Model`
|
|||
|
|
2. 新增 Model Importer Inspector
|
|||
|
|
3. 实现 `Apply/Reimport`
|
|||
|
|
4. 实现拖模型到场景生成 `GameObject` 层级
|
|||
|
|
|
|||
|
|
验收标准:
|
|||
|
|
|
|||
|
|
1. 从 editor 可完整配置模型导入
|
|||
|
|
2. 拖入场景后层级与局部变换正确
|
|||
|
|
|
|||
|
|
### Phase 6:清理过渡路径与补齐文档测试
|
|||
|
|
|
|||
|
|
目标:
|
|||
|
|
|
|||
|
|
1. 收紧旧路径,避免双轨架构长期并存
|
|||
|
|
|
|||
|
|
任务:
|
|||
|
|
|
|||
|
|
1. 评估并逐步弱化“source file 直接由 `MeshLoader` 作为主入口”的旧路径
|
|||
|
|
2. 清理命名、文档、注释、测试目录结构
|
|||
|
|
3. 输出阶段总结
|
|||
|
|
|
|||
|
|
验收标准:
|
|||
|
|
|
|||
|
|
1. 主链路清晰,旧路径只保留必要兼容
|
|||
|
|
2. 文档与测试同步完成
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 13. 关键风险与应对
|
|||
|
|
|
|||
|
|
### 13.1 最大风险:`LocalID` 不稳定
|
|||
|
|
|
|||
|
|
风险:
|
|||
|
|
|
|||
|
|
1. reimport 后子资产重排
|
|||
|
|
2. 场景与 prefab 引用失效
|
|||
|
|
|
|||
|
|
应对:
|
|||
|
|
|
|||
|
|
1. 在 Phase 1 之前先写清 `LocalID` 规则
|
|||
|
|
2. 在 Phase 3 前就建立稳定性测试
|
|||
|
|
|
|||
|
|
### 13.2 第二风险:轴系与缩放规则前后不一致
|
|||
|
|
|
|||
|
|
风险:
|
|||
|
|
|
|||
|
|
1. 同一模型在 direct load、artifact load、scene instantiate 三条路径下结果不一致
|
|||
|
|
|
|||
|
|
应对:
|
|||
|
|
|
|||
|
|
1. 明确标准化规则只允许一个真值来源
|
|||
|
|
2. 写入 importer settings 并进入测试
|
|||
|
|
|
|||
|
|
### 13.3 第三风险:编辑器体验与底层数据不同步
|
|||
|
|
|
|||
|
|
风险:
|
|||
|
|
|
|||
|
|
1. Inspector 改了设置但 reimport 行为不稳定
|
|||
|
|
2. Project 面板显示的是 `Model`,内部实际仍按 `Mesh` 走
|
|||
|
|
|
|||
|
|
应对:
|
|||
|
|
|
|||
|
|
1. 先完成 Resource/AssetDatabase 语义,再接 editor UI
|
|||
|
|
2. 不允许 editor 先行伪装完成
|
|||
|
|
|
|||
|
|
### 13.4 第四风险:过渡期双轨逻辑长期共存
|
|||
|
|
|
|||
|
|
风险:
|
|||
|
|
|
|||
|
|
1. `MeshLoader` source import 与 `ModelImporter` source import 两套路径并行,长期维护成本失控
|
|||
|
|
|
|||
|
|
应对:
|
|||
|
|
|
|||
|
|
1. 在 Phase 6 明确收紧旧路径
|
|||
|
|
2. 把 source import 主入口统一到 `ModelImporter`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 14. 本轮完成标志
|
|||
|
|
|
|||
|
|
当以下条件同时成立时,本轮才算真正完成:
|
|||
|
|
|
|||
|
|
1. `.obj/.fbx/.gltf/.glb/...` 的主资产统一为 `Model`
|
|||
|
|
2. `Model` artifact 已正式落地并进入 `ResourceManager`
|
|||
|
|
3. `OBJ` 能导入成简化 `Model`
|
|||
|
|
4. `FBX` 能导入成保留 hierarchy 的静态 `Model`
|
|||
|
|
5. 模型导入设置已写入 `.meta` 并进入 reimport 逻辑
|
|||
|
|
6. editor 中已具备 Model Importer Inspector
|
|||
|
|
7. 拖模型到场景时会生成 `GameObject` 层级,而非单个烘平 mesh
|
|||
|
|
8. 子资产 `LocalID` 在普通 reimport 下稳定
|
|||
|
|
9. 测试已覆盖真实 `FBX` fixture 的关键路径
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 15. 一句话结论
|
|||
|
|
|
|||
|
|
这一轮不是“给 FBX 补支持”,而是把 XCEngine 的外部模型资源体系从“以 `Mesh` 为主资产的静态导入器”升级成“以 `Model` 为主资产、以子资产和稳定 reimport 为基础、可持续扩展到骨骼动画的 Unity 风格模型工作流”。
|