11 KiB
MetaCore 模型工作流 P0 实施计划
生成时间:2026-04-11
状态:执行稿
范围:Task 06 / 01 / 03 / 02 / 04 / 05
目的
这份文档把 metacore-model-workflow-p0-task-cards.md 再往下压一层,直接落到:
- 要改哪些状态
- 要加哪些接口
- 哪些面板负责什么
- 每一步怎么验收
目标是让后续实现阶段尽量少临场改设计。
推荐实施顺序
建议严格按下面顺序推进:
- Task 06:资源选择状态统一
- Task 01:Project 面板最小版
- Task 03:模型资源 Inspector 最小版
- Task 02:模型 / Prefab 拖拽到 Scene / Hierarchy
- Task 04:对象材质槽编辑
- Task 05:材质资源 Inspector 最小版
原因:
- 没有独立资源选择状态,Project 面板和 Inspector 没法稳
- 没有 Project 面板,后面的资源拖拽和资源 Inspector 都无从谈起
- 没有模型资源 Inspector,资源选中就没有价值
- 材质槽编辑和材质资源编辑必须等资源选择主链稳定后再上
Step 1:资源选择状态统一
目标
让编辑器同时理解两套不同的选择:
- 场景对象选择
- 资源选择
并明确 Inspector 当前展示哪一种。
当前问题
目前编辑器核心状态明显偏向对象选择:
HierarchyScene ViewInspector
基本都围绕 GameObject 选中展开。
但一旦引入 Project 面板,编辑器必须明确:
- 选中资源时,Inspector 显示资源
- 选中对象时,Inspector 显示对象
建议改动
A. 在 MetaCoreEditorContext 中新增资源选择状态
建议新增最小状态:
std::optional<MetaCoreAssetGuid> SelectedAssetGuidstd::filesystem::path SelectedAssetPathstd::string SelectedAssetType
也可以封成:
struct MetaCoreSelectedAssetState {
MetaCoreAssetGuid AssetGuid{};
std::filesystem::path RelativePath{};
std::string AssetType{};
bool Valid = false;
};
B. 新增最小 API
建议在 MetaCoreEditorContext.h 增加:
void ClearSelectedAsset();void SelectAsset(const MetaCoreAssetRecord& record);bool HasSelectedAsset() const;const MetaCoreSelectedAssetState& GetSelectedAsset() const;
C. 明确 Inspector 模式
建议增加一个轻量枚举:
enum class MetaCoreInspectorTargetKind {
None = 0,
SceneObject,
Asset
};
由 EditorContext 决定当前 Inspector 看谁。
D. 事件广播
当前已有 MetaCoreEditorEventBus,建议增加:
- 复用
SelectionChanged - 或新增
AssetSelectionChanged
如果不想扩事件类型,SelectionChanged 也能先扛住,但消息体里最好补一位,区分对象/资源选择。
落点
完成标准
- 选中对象时 Inspector 仍按对象逻辑显示
- 选中资源时 Inspector 切到资源模式
- 二者切换时状态不互相污染
Step 2:Project 面板最小版
目标
做出最小可用的资源工作台。
推荐 UI 结构
左栏:目录树
首批固定展示:
AssetsScenesRuntime
Library 不作为主工作目录。
右栏:资源列表
当前目录下显示:
- 文件夹
- 资源项
建议首批字段:
- 名称
- 类型
- 来源类型(可选)
交互设计
单击目录
- 更新当前浏览目录
单击资源
- 写入
EditorContext的资源选择状态 - Inspector 联动
双击资源
首批建议:
- 场景:加载 Scene
- Prefab:先不做独立打开,可先选中并允许实例化
- 模型/材质/纹理:先只选中,不双开
最小动作
建议面板工具栏有:
RefreshNew Folder
资源项右键菜单首批支持:
ReimportCopy Relative Path
数据来源
依赖:
GetDirectoriesUnder(relativeDirectory)GetAssetsUnder(relativeDirectory)
落点
- MetaCoreBuiltinEditorModule.cpp
- 若当前已有 Project 面板骨架,则优先在既有面板内扩展,不新开第二套实现
完成标准
- 用户可以浏览项目目录
- 用户可以选中资源
- 用户可以执行刷新
- 用户可以对单资源执行重导入
Step 3:模型资源 Inspector 最小版
目标
让选中模型资源这件事有足够信息密度。
建议 Inspector 结构
基础信息区
- 名称
- 相对路径
ImporterIdSourceFormatSourceHash
统计区
Mesh CountMaterial CountTexture CountNode Count
摘要区
- Mesh 列表
- 名称
- PrimitiveCount
- Material 列表
- 名称
- Texture 列表
- 相对路径
数据读取方式
建议流程:
- 从
SelectedAssetGuid找MetaCoreAssetRecord - 读
PackagePath - 反序列化
MetaCoreModelAssetDocument - 在 Inspector 渲染
最小动作
ReimportCopy Relative Path
落点
完成标准
- 选中模型资源时能显示完整最小摘要
glTF / glb / generic model都能显示
Step 4:模型 / Prefab 拖拽到 Scene / Hierarchy
目标
把现有实例化服务接到编辑器交互里。
拖拽载荷建议
建议定义一个最小内部拖拽 payload:
struct MetaCoreAssetDragPayload {
MetaCoreAssetGuid AssetGuid{};
std::string AssetType{};
std::filesystem::path RelativePath{};
};
首批只要支持:
modelprefabmaterial
Scene 接收规则
模型
- 调
InstantiateModelAsset(...)
Prefab
- 调
InstantiatePrefab(...)
Hierarchy 接收规则
模型
- drop 到某对象时,将该对象作为
forcedParentId
Prefab
- 同理
首批先不做
- 3D 光标落点
- 基于鼠标位置自动设置世界坐标
- 材质拖到 Scene 视口
落点
Project面板的资源项开始拖拽Scene View面板接收Hierarchy面板节点接收
推测落点主要仍是:
完成标准
- 模型可拖到 Scene
- 模型可拖到 Hierarchy 节点
- Prefab 可拖到 Scene / Hierarchy
- drop 后自动选中新建根对象
Step 5:对象 Inspector 中的材质槽编辑
目标
让模型实例不只是“摆进去”,而是真的能改材质引用。
当前基础
MetaCoreComponents.h 中已经有:
MeshAssetGuidMaterialAssetGuids
这说明对象级引用结构已经具备。
首批实现建议
A. 在 MeshRenderer Inspector 中列出材质槽
至少显示:
- 槽位索引
- 当前材质名
B. 用下拉框替换材质
候选来源:
- 资产数据库中
Type == "material"的资源
C. 支持从 Project 面板拖入
拖一个材质资源到对应槽位时:
- 更新
MaterialAssetGuids[slot]
最小约束
- 如果对象当前没有足够槽位,首批可只支持已有槽位替换
- 不在 P0 里做 submesh 级复杂编辑器
落点
完成标准
- 用户能替换对象材质槽
- 修改后重新选择对象仍能看到结果
- Scene 保存重开后引用仍保留
Step 6:材质资源 Inspector 最小版
目标
让 MetaCoreMaterialAssetDocument 变成真正能编辑的资源。
建议显示字段
- 名称
- ShaderModel
- BaseColor
- BaseColorTexture
- NormalTexture
- Metallic
- Roughness
- MetallicRoughnessTexture
- EmissiveColor
- EmissiveTexture
- AlphaMode
- AlphaCutoff
- DoubleSided
建议编辑方式
标量 / 开关
DragFloatCheckboxCombo
资源引用
- 下拉选择
- 后续支持从 Project 面板拖入
保存策略
首批建议直接:
- 读材质资源包
- 反序列化
MetaCoreMaterialAssetDocument - 修改字段
- 写回 package
运行时联动
P0 阶段至少要求:
- 编辑后重新渲染当前对象时能读到更新值
如果实时联动太复杂,也应保证:
- 再次选中对象 / 刷新场景时能反映资源修改
落点
完成标准
- 选中材质资源能显示参数
- 能修改并写回资源
- 引用该材质的对象能反映修改结果
建议接口补充
为了减少 EditorModule 直接拼太多读写逻辑,建议补一层轻量资源编辑服务,至少先支持模型和材质:
class MetaCoreIAssetEditingService : public MetaCoreIEditorService {
public:
[[nodiscard]] virtual std::optional<MetaCoreModelAssetDocument> LoadModelAsset(const MetaCoreAssetGuid& assetGuid) const = 0;
[[nodiscard]] virtual std::optional<MetaCoreMaterialAssetDocument> LoadMaterialAsset(const MetaCoreAssetGuid& assetGuid) const = 0;
[[nodiscard]] virtual bool SaveMaterialAsset(const MetaCoreAssetGuid& assetGuid, const MetaCoreMaterialAssetDocument& document) = 0;
};
这不是 P0 必须,但非常建议。
否则:
Project面板- 资源 Inspector
- 材质编辑器
都会在 UI 层重复拼 package 读写逻辑。
每步验收命令建议
每完成一个步骤后,至少做下面验证:
cmake --build --preset build-debug
ctest --preset test-debug
同时建议补对应 smoke test:
- 资源选择状态切换
- Project 面板基础交互
- 模型资源 Inspector 读取
- 拖拽实例化
- 材质槽替换
- 材质资源写回
风险点
1. 资源选择状态与对象选择状态互相覆盖
这是最容易出现的 UI 脏状态问题。
应优先解。
2. Inspector 读写逻辑散落
如果不抽轻量资源编辑服务,后面会重复实现 package 读写。
3. 对象材质参数和材质资源参数边界混乱
当前 MeshRenderer 仍带着一部分材质字段。
P0 阶段先容忍,但实现时必须有意识:
- 资源 Inspector 编辑的是资源
- 对象 Inspector 编辑的是引用
4. 拖拽协议分散
建议早一点统一 asset drag payload,避免:
- Project 一套
- Hierarchy 一套
- Scene 一套
后面难收。
最终建议
P0 实施时最重要的不是功能总数,而是:
每一步都要让“资源 -> Inspector -> Scene/Hierarchy”这条链更顺,而不是再加新的孤立能力。
这条链一旦立住,MetaCore 的观感会马上从“会导模型的工具”变成“开始像编辑器的引擎”。