Skip to content

Stage03|Runtime Objects & Assets ​

Lesson023|UUID、.meta、AssetDB 和属性引用是什么关系? ​

Tags: #Creator2.x #Stage03 #UUID #Meta #AssetDB #AssetReferenceDifficulty: ⭐⭐⭐⭐☆


一、本课从一个常见事故开始 ​

项目里有一张图片:

text
assets/resources/ui/shop/coin.png

几十个 Prefab 都引用它。某天你把它移动到:

text
assets/resources/common/icons/coin.png

如果通过 Creator 编辑器移动,引用通常还能保留;如果在资源管理器里复制、删除、重建,部分 Prefab 可能突然丢图。

路径明明只是字符串,为什么编辑器内移动可以保留引用?为什么删除 .meta 再生成就可能失效?

核心答案是:

Creator 资源引用依赖稳定身份,而不是只依赖文件路径。UUID 提供身份,.meta 保存导入和身份信息,AssetDB 负责维护资源数据库与引用关系。


二、本课目标 ​

完成本课后,你应该能够:

  1. 解释路径、UUID、.meta、AssetDB 各自负责什么。
  2. 说明为什么移动资源和删除重建资源是不同操作。
  3. 解释 Inspector 属性引用如何从编辑器保存到运行时恢复。
  4. 正确处理资源移动、重命名、替换和复制。
  5. 识别 UUID 冲突、Missing Asset、导入未完成和无关 .meta 重写。
  6. 知道 library/、temp/ 等生成目录为什么不能手工修补。

三、路径和身份不是一回事 ​

现实类比:

text
文件路径像家庭住址
UUID 像身份证号码

人搬家后,地址改变,但仍然是同一个人。资源移动后:

text
旧路径:ui/shop/coin.png
新路径:common/icons/coin.png
UUID:保持不变

依赖 UUID 的引用可以继续找到它。

相反,如果删除原资源并创建一张同名图片:

text
路径:看起来相同
UUID:已经变化

从资源系统角度,它是一个新资源,旧引用不应被假定自动指向它。


四、.meta 文件保存什么 ​

Creator 导入 assets 中的资源时,会生成或更新对应 .meta。它可能包含:

text
资源 UUID
导入器类型
导入设置
子资源信息
平台相关配置

不同资源类型的 .meta 内容不同。例如图片可能产生 Texture 和 SpriteFrame 等子资源信息;脚本、Prefab、音频也有各自导入配置。

.meta 的两个关键作用 ​

text
稳定资源身份
+
保存编辑器导入配置

因此 .meta 不是普通缓存,也不是可以随意复制的模板。


五、为什么不能手工伪造 UUID ​

如果两个资源拥有相同 UUID,AssetDB 无法可靠判断引用目标:

text
coin.png.meta → uuid: A
gem.png.meta  → uuid: A

可能造成:

  • 引用指向错误资源。
  • 资源导入冲突。
  • Prefab/Scene 显示异常。
  • 不同开发机结果不一致。
  • 构建产物与编辑器预览不一致。

复制资源作为新资源时,不应复用旧 .meta。应该让 Creator 编辑器/AssetDB 为新资源生成新的身份。


六、AssetDB 是什么 ​

AssetDB 可以理解为编辑器侧的资源数据库和导入协调器:

text
监视 assets 变化
→ 识别资源类型
→ 读取或生成 .meta
→ 分配和维护 UUID
→ 执行导入器
→ 生成编辑器/运行时需要的数据
→ 更新资源和依赖关系

AssetDB 连接:

text
磁盘文件
↔ 编辑器资源面板
↔ UUID / .meta
↔ Scene / Prefab 引用
↔ 导入产物

因此在操作 assets 后,必须等待 Creator 导入完成,再预览或构建。

compile 只说明脚本编译,并不等于图片、Prefab、音频等资源已经完成导入。


七、Inspector 属性引用如何保存 ​

脚本属性:

ts
@property(cc.SpriteFrame)
coinFrame: cc.SpriteFrame = null;

在 Inspector 中拖入 coin SpriteFrame 后,序列化资源需要记录目标 Asset 身份。高层模型是:

text
ShopItemView.coinFrame
    ↓ 保存资源引用
UUID / 子资源身份
    ↓ AssetDB 解析
coin SpriteFrame Asset
    ↓ 运行时加载
cc.SpriteFrame 对象

这与 Prefab 内部组件引用不同:

text
内部引用:指向同一 Scene/Prefab 对象图中的 Node/Component
资源引用:指向 AssetDB 管理的外部 Asset

两种引用都需要稳定身份,但恢复机制和生命周期边界不同。


八、移动、重命名、替换、复制有什么区别 ​

1. 移动或重命名已有资源 ​

目标:同一个资源换路径。

正确做法:

text
在 Creator 编辑器 Assets 面板中操作
→ AssetDB 同步文件和 .meta
→ UUID 保持
→ 引用继续指向原资源

操作后等待导入完成并检查 Git 变更。

2. 替换已有资源内容 ​

目标:保持所有引用,但换图片/音频/JSON 内容。

正确原则:

text
替换源文件内容
保留原有 .meta
让 AssetDB 重新导入

这样可以保留 UUID 和已有引用,同时继续使用原导入配置。

3. 复制为一个新资源 ​

目标:得到可以独立引用的新 Asset。

正确原则:

text
复制源资源
不要复用旧 .meta
让 AssetDB 生成新 UUID

4. 删除后重建同名资源 ​

这是新资源,不应假定旧引用保留。路径相同不能代替 UUID 身份。


九、为什么不能修补生成目录 ​

常见生成目录包括:

text
library/
temp/
local/
build/
native/

它们保存编辑器、预览、构建或本机缓存产物。直接修改有三个问题:

  1. 下一次导入或构建会覆盖修改。
  2. 修改只在本机有效,无法修复源资源事实。
  3. 可能让本机看似正常,其他开发机或 CI 仍失败。

正确修复入口应该是:

text
assets 中的源资源
编辑器 Inspector 设置
编辑器资源操作
项目脚本或配置源文件

而不是生成目录。


十、贯穿案例:coin.png 的完整身份链 ​

导入阶段 ​

text
coin.png 放入 assets
→ AssetDB 识别图片
→ 生成 coin.png.meta
→ 分配 UUID
→ 根据导入设置生成 Texture / SpriteFrame 子资源

绑定阶段 ​

text
把 coin SpriteFrame 拖入 Prefab 的 Sprite
→ Prefab 保存资源引用
→ 引用指向 coin 的资源身份

移动阶段 ​

text
在编辑器移动 coin.png
→ coin.png 和 .meta 同步移动
→ UUID 不变
→ Prefab 引用仍有效

错误重建 ​

text
在资源管理器删除 coin.png 和 .meta
→ 再复制一个同名 coin.png
→ AssetDB 生成新 UUID
→ 原 Prefab 仍引用旧 UUID
→ Inspector 显示 Missing Asset 或空引用

十一、编辑器验证实验 ​

只在 Creator 编辑器中移动、重命名和复制资源。不要手工编辑 .meta,不要打开 Prefab/Scene 文件替换 UUID。

实验目标 ​

验证:

text
移动路径不等于更换身份
复制新资源必须获得新身份
替换内容可以保留原引用

准备 ​

  1. 在 Creator 2.4.x 中创建 AssetIdentityLab 场景。
  2. 导入一张测试图片 coin.png。
  3. 创建 Sprite 节点并在 Inspector 中绑定 coin 的 SpriteFrame。
  4. 保存场景,等待资源导入完成。
  5. 确认场景预览正常显示。

实验 A:编辑器内移动 ​

  1. 在 Assets 面板中新建 common/icons 目录。
  2. 使用 Creator 编辑器把 coin.png 移入该目录。
  3. 等待导入完成。
  4. 返回场景,检查 SpriteFrame 引用。
  5. 运行预览。

预期:

text
路径改变
引用仍存在
Sprite 仍正常显示

观察 Git 时,源文件和对应 .meta 应一起移动,而不是生成完全无关的新身份。

实验 B:复制为新资源 ​

  1. 在 Creator 编辑器中复制 coin,得到 coin-copy.png。
  2. 等待 AssetDB 导入。
  3. 创建第二个 Sprite,绑定 coin-copy。
  4. 在 Inspector 中观察两个资源是独立条目。

预期:

text
两个资源路径不同
两个资源身份不同
修改第二个 Sprite 的引用不影响第一个 Sprite 的绑定

实验 C:替换原内容 ​

  1. 准备一张同规格但视觉明显不同的图片。
  2. 用它替换 coin.png 的文件内容,保留原 coin.png.meta。
  3. 回到 Creator,等待重新导入。
  4. 运行预览。

预期:

text
原 Sprite 引用没有丢失
显示内容变成新图片
导入设置继续沿用原 .meta

十二、实验失败时怎么排查 ​

移动后引用丢失 ​

text
是否通过 Creator 编辑器移动
→ .meta 是否和源文件一起移动
→ 是否误删后重新复制
→ AssetDB 是否仍在导入
→ 控制台是否有 UUID 冲突

复制后两个资源冲突 ​

text
是否连旧 .meta 一起复制
→ 两份 .meta 是否出现同 UUID
→ 关闭手工修补,回到 Creator 让 AssetDB 重新生成新资源身份

替换图片后显示异常 ​

text
新图片尺寸和格式是否符合预期
→ 原导入设置是否仍适用
→ SpriteFrame 边界、九宫格等设置是否需要调整
→ AssetDB 是否导入完成

十三、真实项目案例:分支合并导致大面积丢图 ​

现象 ​

合并分支后,几十个 Prefab 出现 Missing SpriteFrame,Git 里有大量 .meta 被删除并重新创建。

根因模式 ​

某个分支整理目录时使用文件管理器移动资源,或者冲突解决时把 .meta 当作缓存删除。Creator 随后为资源生成新 UUID,旧 Prefab 仍指向原 UUID。

正确恢复思路 ​

text
停止继续导入和保存受影响 Prefab
→ 通过 Git 找回原资源对应的 .meta
→ 恢复资源与原 .meta 的配对关系
→ 用 Creator 打开项目并等待 AssetDB 导入
→ 检查引用恢复情况
→ 只对确实无法恢复的引用在 Inspector 中重新绑定

重点是恢复原身份,而不是给所有 Prefab 批量替换一个猜测出来的 UUID。

交付前检查 ​

  • 新资源是否有编辑器生成的 .meta。
  • 移动资源是否保持原 .meta。
  • 是否出现无关 .meta 大面积重写。
  • 是否误提交 library/、temp/、local/、build/。
  • Creator 是否完成资源导入。

十四、常见误区 ​

误区一:资源引用只依赖路径 ​

编辑器序列化引用需要稳定身份,路径主要服务组织和运行时路径加载。

误区二:.meta 是缓存,删了会自动恢复 ​

重新生成的 .meta 可能包含新 UUID,旧引用无法自动知道它是同一个逻辑资源。

误区三:复制新资源时应该复制旧 .meta ​

这会制造 UUID 冲突。新资源应由 AssetDB 生成新身份。

误区四:替换图片时应该删除旧 .meta ​

替换内容应保留旧 .meta,这样才能保留原有引用和导入设置。

误区五:脚本 compile 成功就说明资源导入完成 ​

脚本编译和资源导入是不同流程。

误区六:编辑 library 可以快速修好引用 ​

library 是生成产物,修补不能成为可复现的源代码事实。


十五、练习 ​

A. 概念题 ​

  1. 路径和 UUID 分别解决什么问题?
  2. .meta 为什么需要纳入版本控制?
  3. AssetDB 在资源流程中负责什么?
  4. 内部 Node 引用与外部 Asset 引用有什么区别?

B. 操作判断题 ​

判断以下操作是否正确,并说明原因:

  1. 用新图片覆盖旧 icon.png,保留 icon.png.meta。
  2. 复制 icon.png 和 icon.png.meta,作为新的 icon-red.png。
  3. 在 Creator Assets 面板中移动 Prefab。
  4. 修改 library/ 中的导入产物,让本机预览恢复。
  5. 资源整理完成后,只运行脚本 compile,不打开 Creator。

C. 故障诊断题 ​

合并代码后出现:

text
Duplicate UUID
多个 Prefab 引用错误图片
Git 中新增了大量 .meta

请给出停止损失、确认原因和恢复引用的步骤。


十六、练习参考答案 ​

A. 概念题答案 ​

  1. 路径用于组织和定位文件;UUID 用于在移动、重命名等情况下维持稳定资源身份。
  2. .meta 包含 UUID 和导入设置,缺失会改变资源身份或导入结果。
  3. AssetDB 监视 assets、生成/读取 .meta、执行导入器、维护资源数据库和引用关系。
  4. 内部引用指向同一序列化对象图中的对象;外部引用指向 AssetDB 管理的 Asset。

B. 操作判断答案 ​

  1. 正确。它保留资源身份和导入设置,AssetDB 会重新导入内容。
  2. 错误。新资源复用旧 .meta 会产生 UUID 冲突。
  3. 正确。编辑器可以同步维护源资源和 .meta。
  4. 错误。生成目录会被覆盖,也无法修复其他环境。
  5. 错误。脚本 compile 不等于完整资源导入,应打开 Creator 等待 AssetDB 完成。

C. 故障诊断答案 ​

text
1. 暂停保存 Scene/Prefab 和继续整理资源。
2. 检查 Git diff,找出哪些 .meta 被复制、删除或重建。
3. 搜索重复 UUID,确认冲突资源对。
4. 从正确基线恢复已有资源的原 .meta。
5. 对真正新增的资源移除复用的旧 .meta,让 AssetDB 生成新身份。
6. 用 Creator 打开项目,等待导入完成。
7. 检查关键 Prefab 和场景引用。
8. 检查没有生成目录和无关 .meta 重写进入提交。

十七、本课总结 ​

text
路径描述资源在哪里。
UUID 描述资源是谁。
.meta 保存资源身份和导入设置。
AssetDB 维护文件、身份、导入和引用之间的关系。

最终操作原则:

text
移动/重命名:在 Creator 编辑器操作,保留 .meta。
替换内容:保留原 .meta。
复制为新资源:不要复用旧 .meta。
资源变更后:打开 Creator,等待 AssetDB 导入完成。
问题排查:修源资源和引用,不修 library/temp/build。

十八、下一课预告 ​

text
Lesson024|instantiate 一个 Prefab 时发生了什么?

下一课会继续追踪:

text
Prefab 模板
→ 对象图克隆
→ 内部引用重映射
→ 外部 Asset 共享
→ 生命周期
→ instantiate 成本和对象池