Version: 6000.3
语言: 中文
运行时资产管理简介
使用资源系统在运行时加载资产

直接参考资产管理

直接引用资产管理是在 Unity 中运行时管理资产的默认方式。每当您将资产拖到场景场景包含游戏的环境和菜单。将每个唯一的场景文件视为一个独特的关卡。在每个场景中,你放置你的环境、障碍物和装饰品,基本上是将你的游戏设计和构建成碎片。更多信息
请参阅术语表
或通过检查器一个 Unity 窗口,显示有关当前选定游戏对象、资产或项目设置的信息,允许您检查和编辑值。更多信息
请参阅术语表
窗口中,您可以创建对该资产的直接引用。当您构建应用程序时,Unity 会将所有引用的资产保存在与项目中的场景关联的单独文件中。

直接参考概述

在 Unity 中,直接引用是从一个对象到另一个对象的序列化链接。当一个对象持有对另一个对象的直接引用时,它会创建对该对象的依赖关系。当 Unity 创建项目的构建时,它会遵循所有直接引用,以确保构建中包含所有相互引用的对象。

在 C# 代码中,这些引用通常由派生自UnityEngine.ObjectGameObject,MaterialMonoBehaviour.

例如,一个游戏对象Unity 场景中的基本对象,可以表示角色、道具、风景、相机、航路点等。游戏对象的功能由附加到它的组件定义。更多信息
请参阅术语表
直接引用每个Component附加到它,例如Transform,MeshRendererMonoBehaviourscript 和Component保存对其父游戏对象的直接引用。

您还可以使用[SerializeReference]创建对非UnityEngine.Object派生的 C# 对象。

Unity 以不同的方式处理对象引用,具体取决于引用对象是否派生自UnityEngine.Object,或者如果它是引用的 C# 对象[SerializeReference].

Unity 对象引用

如果字段引用派生自UnityEngine.Object,则 Unity 不会序列化整个对象的数据,而是序列化指向该对象的指针。

指针包含以下信息:

  • 全局唯一标识符 (GUID) :一个 128 位 (32 个字符的十六进制) ID,用于唯一标识磁盘上包含目标的资产文件UnityEngine.Object. Unity 项目中的每个资产文件,例如.prefab,.mat,.png,.unity场景文件,以及.cs脚本文件有相应的.meta存储其 GUID 的文件。
  • fileID:该特定资产文件中的目标对象唯一的 64 位 ID。例如,一个预制件一种资产类型,允许您存储包含组件和属性的游戏对象。预制件充当模板,您可以从中在场景中创建新的对象实例。更多信息
    请参阅术语表
    资产包含多个GameObject实例。这些内部组件中的每一个UnityEngine.Object实例有其独特的fileID在该单个预制件文件中。

在内部,Unity 使用PPtr<T>类型。 当 Unity 在运行时将这些对象加载到内存中时,它会将 GUID 和 fileID 对解析为InstanceID,然后使用它来跟踪活动对象。 这InstanceID对于当前 Unity 编辑器会话或运行时实例是唯一的。

如果打开场景文件 (.unity) 或预制件文件 (.prefab) 中,您可以检查对UnityEngine.Object派生类型表示如下:

# A MonoBehaviour on a GameObject referencing a Prefab asset
MonoBehaviour:
  m_ObjectHideFlags: 0
  m_CorrespondingSourceObject: {fileID: 0}
  m_PrefabInstance: {fileID: 0}
  m_PrefabAsset: {fileID: 0}
  m_GameObject: {fileID: 100100000} # Reference to the GameObject this component is on (internal fileID)
  m_Enabled: 1
  m_EditorHideFlags: 1
  m_Script: {fileID: 11500000, guid: f5ee4a4c1e4c3b448a97448840cdf0f41, type: 3} # Reference to the MonoBehaviour script asset (GUID of script file, fileID 11500000 often for MonoBehaviour)
  myTargetPrefab: {fileID: 100100000, guid: 61da4d63ca179b54a97448840cdf0f41, type: 3} # Reference to an external Prefab asset (GUID of Prefab file, fileID 100100000 for the root GameObject within the Prefab)

在此示例中,myTargetPrefab指向: *fileID: 100100000:目标预制件文件中的特定引用对象(可能是根游戏对象)。 *guid: 61da4d63ca179b54a97448840cdf0f41:预制件资产文件的 GUID。 *type: 3:资产的类型。type: 3通常表示预制件或脚本资产。

C# 对象引用

默认情况下,Unity 会序列化任何非派生自UnityEngine.Object按值。这意味着它将对象的全部数据直接嵌入到保存引用的对象的序列化数据中。

您可以使用[SerializeReference]属性来更改此行为,并指示 Unity 通过引用而不是值来存储对普通 C# 对象的引用。如果要允许多个对象在序列化结构中引用同一 C# 对象并避免数据重复,这将非常有用。

您不能使用[SerializeReference]引用UnityEngine.Object-派生类。有关详细信息,请参阅序列化规则

对象跟踪和映射

当 Unity 将资产和场景加载到内存中时,它使用内部数据结构将引用映射到实时对象。这些数据结构包括Ptr,TypeTree,RemapperPersistentManager.为UnityEngine.Object引用,Unity 将序列化的 GUID 和 fileID 对映射到实时 C++Object*指针。为[SerializeReference]对象,Unity 将内部数字 ID 映射到实时对象实例。最后,Unity 将这些 C++ 指针映射到UnityEngine.Object以及代码可以使用的普通 C# 实例。

当 Unity 构建或加载资源时,它会创建一个从根对象开始的依赖关系图,并递归地遍历所有直接引用。Unity 将完整的图形加载到内存中,以便根对象正常运行。

直接引用可能会影响应用程序的生成大小。如果UnityEngine.Object资产直接被项目中任何对象直接引用,然后是该资产(及其直接依赖关系的整个图,通过GUIDfileID成对)包括在内。这意味着仔细管理直接引用对于防止未使用或无意中包含的资产至关重要。

有关 Unity 在构建时创建的文件的更多信息,请参阅构建文件的输出

组织大型资产集

如果你有大量资源列表需要跨多个场景共享,或者在不修改场景文件的情况下进行更新,你可以使用ScriptableObject实例来管理这一点。一个ScriptableObject可以保存对其他资产的直接引用,这些资产充当对项目资产的引用的资产目录。ScriptableObject实例是序列化资产,并在编辑器会话和构建中保留。您可以在多个不同的 MonoBehaviour 实例中重用它们,它们可以帮助减小场景文件大小。有关更多信息,请参阅 ScriptableObject 文档

您还可以使用AssetDatabase.FindAssets查找资产并填充ScriptableObject与数据。

其他资源

运行时资产管理简介
使用资源系统在运行时加载资产