游戏开发小结—— 解决 Unity3d 中缺少预制件的问题
当您开始对 Unity 项目使用源代码控制解决方案时,您可能会在某个时候遇到可怕的 Missing Prefab 或 Missing Reference 错误。在本文中,我们将了解它发生的原因以及如何解决它。
痛苦和难受。您刚刚完成了一个复杂的功能,并且很乐意合并您的代码并切换到另一个分支来执行新功能或一些错误修复。但是当你看到上面的内容时,你的心跳加快了一拍。
我第一次看到这个是在我的资源商店项目 Laser System for Unity 中。我刚刚完成了自动化测试的编写,看起来我必须从头开始,因为测试场景完全被破坏了。
请注意,这里我添加了一个简化的示例,以保持文章简洁。游戏场景通常要复杂得多,即使你知道场景中有哪些资产,你也不一定记得它们的位置、脚本和所有其他东西。基本上,您将不得不重新创建场景!
让我们探索问题以了解其原因,看看解决方案是什么。
Missing references 缺少引用
Unity 使用 .meta 文件来存储有关资源的信息。所有的人。原因是您不能以实际的标准文件格式( .png 例如)编写特定于 Unity 的导入信息。在手册中,第一行明确指出了为什么弄乱这些可能是头痛的主要原因:
当 Unity 导入资源时,它还会存储和管理有关资源的其他数据,例如 Unity 在导入资源时应使用的导入设置,以及资源在整个项目中的使用位置。
简而言之,如果你搞砸了你的 .meta 文件,Unity将不知道你的资源在整个项目中的什么地方使用。让我们看看我的一个有问题的元文件:
fileFormatVersion: 2
guid: 0319338b734134948b260f2b62f12f08
PrefabImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
我的资源的 .meta 文件 receiver_cube.prefab
从本质上讲, .meta 文件是 .yaml 有关资产的格式信息。 guid 用于识别项目中任何位置的资源,包括场景。它在我的测试场景文件中 RotatingEmitterTestScene 使用,如下所示:
…
m_RequiresColorTexture: 0
m_Version: 2
— !u!1001 &1954492174
PrefabInstance:
m_ObjectHideFlags: 0
serializedVersion: 2
m_Modification:
m_TransformParent: {fileID: 0}
m_Modifications:
- target: {fileID: 7170003865817550782, guid: 0319338b734134948b260f2b62f12f08, type: 3}
propertyPath: m_RootOrder
value: 2
objectReference: {fileID: 0}
- target: {fileID: 7170003865817550782, guid: 0319338b734134948b260f2b62f12f08, type: 3}
propertyPath: m_LocalPosition.x
value: -3.36
objectReference: {fileID: 0}
- target: {fileID: 7170003865817550782, guid: 0319338b734134948b260f2b62f12f08, type: 3}
propertyPath: m_LocalPosition.y
value: 0.505
objectReference: {fileID: 0}
…
RotatingEmitterScene 被截断到重要部分
场景也是 .yaml 文件。请注意 guid 修改的目标。场景文件的这一部分将预制件的转换属性与包含位置的片段链接在一起。
浏览上面的示例,您可以了解 Unity 如何使用资源 guid 在其场景文件中将其与某些属性相关联。 .meta 随着文件消失,它没有指向任何有效的资产,换句话说,它 guid 丢失了。
但为什么这又是一个问题呢?如果我删除现有文件,Unity 不会为我的资源生成新 .meta 文件吗?
是的,确实如此。但是,在删除此资产 .meta 的文件之前,它不会提供完全相同 guid 的结果。如果你没有将你的 .meta 文件包含在你的 git 中,那么当你切换分支或拉取别人的提交时,它们不会与你的资产一起使用。如果我这样做,你会看到下面可怕的最终结果。
实际的恐怖:缺少预制件
基本上,您需要执行两个步骤来恢复资产的原始 guid 内容:
识别资产的旧 guid 资产
将资产的新 .meta 文件替换为 guid 旧文件
反之亦然,只要 guid s 匹配即可。
如果你给它起一个好名字,在你的场景中找到一个是最容易的 GameObject :
…
objectReference: {fileID: 0}
- target: {fileID: 7551173367757001988, guid: 0319338b734134948b260f2b62f12f08, type: 3}
propertyPath: m_Name
value: activated_receiver_cube
objectReference: {fileID: 0}
m_RemovedComponents: []
…