Direct reference asset management
Understand how Unity builds and manages assets that you directly reference from your code.
Read time 8 minutesLast updated 20 days ago
Direct reference asset management is the default way of managing assets at runtime in Unity. Whenever you drag an asset into a scene or onto a component through the Inspector window of the Unity Editor, you create a direct reference to that asset. When you build your application, Unity saves any referenced assets in a separate file associated with the scenes in your project.
You can use direct references with instances to efficiently manage large asset sets and reduce build sizes. A benefit of only using direct references is that Unity only includes assets that your project directly references in the build, so your application doesn't load unnecessary or duplicated assets.
ScriptableObjectDirect references have some limitations, as follows:
- When your application runs on the target device, Unity loads the entire asset file into memory before loading a scene. This approach isn't dynamic and you can only load or unload a scene, which might lead to slow load times, especially on devices with less memory.
- At the time of loading, the asset must already be present in the local file system, and can't be hosted on a content delivery network (CDN).
- You can't make incremental content updates and need to rebuild and redeploy your entire application if you want to make changes.
Direct reference overview
In Unity, a direct reference is a serialized link from one object to another. When one object holds a direct reference to another, it creates a dependency on that object. When Unity creates a build of your project, it follows all direct references to make sure that all objects that reference each other are included in the build.
In your C# code, these references are typically held by objects derived from such as , , or .
UnityEngine.ObjectGameObjectMaterialMonoBehaviourFor example, a GameObject directly references each attached to it, such as a , , or a script, and the holds a direct reference back to its parent GameObject.
ComponentTransformMeshRendererMonoBehaviourComponentYou can also use to create references to non- derived C# objects.
[SerializeReference]UnityEngine.ObjectUnity handles object references in different ways depending on if the referenced object is derived from , or if it's a C# object referenced with .
UnityEngine.Object[SerializeReference]Unity object references
If a field references an object derived from , then Unity doesn't serialize the entire object's data, and instead serializes a pointer to that object.
UnityEngine.ObjectThe pointer contains the following information:
- A global unique identifier (GUID): A 128-bit (32-character hexadecimal) ID that uniquely identifies the asset file on disk that contains the target. Every asset file in your Unity project, such as ,
.prefab,.mat,.pngscene files, and.unityscript files, has a corresponding.csfile that stores its GUID..meta - A fileID property: A 64-bit ID that is unique to the target object within that specific asset file. For example, a prefab asset contains multiple instances with their own components. Each of these internal
GameObjectinstances has its own uniqueUnityEngine.Objectwithin that single prefab file.fileID - A type property: An integer that tells Unity how to locate the referenced asset file on disk. This property is only present in cross-file references. Refer to Type field values for details.
Internally, Unity represents these references with a type. When Unity loads these objects into memory at runtime, it resolves the GUID and fileID pair to an , which it then uses to track the live object. The is unique to the current Unity Editor session or runtime instance.
PPtr<T>InstanceIDInstanceIDReference formats
Unity serializes object references in one of three formats depending on whether the target is in the same file, in a different file, or is unassigned:
- Null reference: means no object is referenced (equivalent to
{fileID: 0}in C#).null - Local (intra-file) reference: contains only a fileID value. References another object within the same serialized file, such as a component referencing the
{fileID: XXXX}it's attached to.GameObject - Cross-file (external) reference: contains a fileID, GUID, and type value. References an object in a different asset file.
{fileID: XXXX, guid: YYYY, type: Z}
Example
Open a scene file () or a prefab file () in a text editor for an example of how Unity serializes these references. The following example shows a component in a scene file:
.unity.prefabMonoBehaviour--- !u!114 &9394472MonoBehaviour: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 9394470} m_Enabled: 1 m_EditorHideFlags: 0 m_Script: {fileID: 11500000, guid: 172515602e62fb746b5d573b38a5fe58, type: 3} m_Name: m_EditorClassIdentifier: m_IsGlobal: 0 priority: 70.96 blendDistance: 3 weight: 1 sharedProfile: {fileID: 11400000, guid: 1beb731b8b5fc434c974ac87889eab21, type: 2}
The document header identifies this as a MonoBehaviour (class ID ) with fileID in this scene file. For more information about the YAML document structure, refer to Format of text serialized files.
--- !u!114 &93944721149394472This example contains all three reference formats:
-
Null references:,
m_CorrespondingSourceObject, andm_PrefabInstanceusem_PrefabAssetbecause this object is not part of a prefab instance.{fileID: 0} -
Local reference:points to the
m_GameObject: {fileID: 9394470}this component is attached to, which is another object in the same scene file with fileIDGameObject.9394470 -
Cross-file references:
- references the MonoScript asset for this component's C# class. The GUID identifies the script's
m_Script: {fileID: 11500000, guid: ..., type: 3}file,.csidentifies the MonoScript object inside that file, and11500000indicates an imported asset.type: 3 - references a Volume Profile stored as a ScriptableObject in a
sharedProfile: {fileID: 11400000, guid: ..., type: 2}file. The GUID identifies the asset file,.assetidentifies the object inside that file, and11400000indicates a source asset that Unity reads directly.type: 2
Type field values
The value in a cross-file reference tells Unity how to resolve the referenced asset's file path from the GUID:
typeValue | Name | Description | Examples |
|---|---|---|---|
| NonAsset | Reference to a built-in resource or non-asset file. The GUID is a constant identifier (such as | Built-in primitive meshes, default shaders, built-in extra resources. |
| SourceAsset | Reference to a source asset that Unity reads directly from the project's asset folders. The GUID maps to a file in a registered asset folder. | Materials ( |
| PrimaryArtifact | Reference to an asset that goes through import processing. The GUID maps to a source file, but Unity resolves the reference to the imported artifact in the | Scripts ( |
C# object references
By default, Unity serializes any objects not derived from by value. This means that it embeds the entire data of the object directly into the serialized data of the object that holds the reference.
UnityEngine.ObjectYou can use the attribute to change this behavior and instruct Unity to store references to plain c# objects by reference rather than value. This is useful if you want to allow multiple objects to reference the same C# object within a serialized structure and avoid data duplication.
[SerializeReference]You can't use to reference a -derived class. For more information, refer to Serialization rules.
[SerializeReference]UnityEngine.ObjectObject tracking and mapping
When Unity loads assets and scenes into memory, it uses internal data structures to map references to live objects. These data structures include , , , and . For references, Unity maps the serialized GUID and fileID pairs to a live C++ . The C++ has a pointer to the associated C# and finally, the C# object references back to the associated C++ object via the instance ID.
InstanceIDPPtrRemapperPersistentManagerUnityEngine.ObjectObjectObjectUnityEngine.ObjectFor objects, Unity maps managed reference IDs to live object instances. For details see ManagedReferenceUtility.GetManagedReferenceIdForObject.
[SerializeReference]When Unity builds or loads assets, it creates a dependency graph starting from the root object and recursively traverses all direct references. Unity loads the complete graph into memory so the root object functions correctly.
Direct references can impact the build size of your application. If a asset is directly referenced by any object in your project that makes it into the build, then that asset (and its entire graph of direct dependencies, resolved via and pairs) are included. This means careful management of direct references is crucial to prevent unused or unintentionally included assets.
UnityEngine.ObjectGUIDfileIDFor more information about the files Unity creates when it makes a build, refer to Content output of a build.
Organizing large asset sets
If you have large lists of assets that you need to share across multiple scenes, or update without modifying scene files, you can use a instance to manage this. A can hold direct references to other assets, which act as an asset catalog of references to your project's assets. instances are serialized assets and persist across Editor sessions and builds. You can reuse them across multiple different MonoBehaviour instances, and they can help reduce scene file size. For more information, refer to the ScriptableObject documentation.
ScriptableObjectScriptableObjectScriptableObjectYou can also use to find assets and populate a with the data.
AssetDatabase.FindAssetsScriptableObject