导入映射:名称不能承担跨工具节点身份

自动关联目录:导入映射:名称不能承担跨工具节点身份

核心判断:本地预览器与 UE Cook 工具会为同一源文件生成不同临时 NodeId;跨工具迁移选择、动画和材质配置时,名称只能参与判别,不能成为身份。

一、业务冲突

创作者在轻量预览中勾选网格、配置贴图或指定动画对象,真正 Cook 却由另一套解析器完成。两端节点遍历顺序、依赖展开和内部 ID 不同;同名对象、重复材质或导出器升级都会让按名称恢复的配置落到错误目标。

二、实际实现

导入层先验证两端读取的是同一源摘要,再用源对象 key、对象类型、序号、对象总数、父序号和名称组成适配条件。只有候选唯一且不存在多对一时才迁移选择或节点配置;旧检查结果无法唯一匹配会要求重新选择,而不是猜测。动画还冻结原始源身份,非可选材质依赖也进入绑定。

三、值得保留

这承认了“内容身份”和“某个解析器的 NodeId”不是一回事。适配器显式处理旧 Schema,并对一对多、多对一和源摘要变化 fail closed。相比保存数组下标或显示名,它保住了用户意图。

四、结构性缺陷

复合匹配仍是推导身份:父序号、对象总数或导出顺序变化都可能让本质未变的对象失配。条件散落在选择、动画、贴图配置和缺失引用多个函数中,若新增一种配置却漏用同一适配规则,会再次分叉。

五、目标设计

struct SourceObjectIdentity {
    Hash sourceFile;
    StableExporterId object;   // 优先使用源工具持久 GUID
    ObjectKind kind;
    Optional<Hash> topologySignature;
};

BindResult Bind(Identity oldId, ParsedScene current) {
    if (auto exact = current.Find(oldId.object)) return Exact(exact);
    auto candidates = current.FindBySignature(oldId);
    return candidates.Size() == 1 ? Migrated(candidates[0]) : Ambiguous(candidates);
}

所有导入配置只引用统一 SourceObjectIdentity;启发式迁移输出显式 Mapping Report,并要求歧义项人工确认。Cook 临时 NodeId 只存在于一次运行内部。

六、取舍与验证

源格式未提供 GUID 时仍需复合签名,稳定性与可迁移性之间没有零成本答案。用同名节点、重排、插入兄弟、父级改名和不同解析器版本做 golden mapping;任何歧义必须可见,不能静默选第一个。