Direct reference asset management is the default way of managing assets at runtime in Unity. Whenever you drag an asset into a sceneA Scene contains the environments and menus of your game. Think of each unique Scene file as a unique level. In each Scene, you place your environments, obstacles, and decorations, essentially designing and building your game in pieces. More info
See in Glossary or onto a component through the InspectorA Unity window that displays information about the currently selected GameObject, asset or project settings, allowing you to inspect and edit the values. More info
See in Glossary 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.
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 UnityEngine.Object such as GameObject, Material, or MonoBehaviour.
For example, a GameObjectThe fundamental object in Unity scenes, which can represent characters, props, scenery, cameras, waypoints, and more. A GameObject’s functionality is defined by the Components attached to it. More info
See in Glossary directly references each Component attached to it, such as a Transform, MeshRenderer, or a MonoBehaviour script, and the Component holds a direct reference back to its parent GameObject.
You can also use [SerializeReference] to create references to non-UnityEngine.Object derived C# objects.
Unity handles object references in different ways depending on if the referenced object is derived from UnityEngine.Object, or if it’s a C# object referenced with [SerializeReference].
If a field references an object derived from UnityEngine.Object, then Unity doesn’t serialize the entire object’s data, and instead serializes a pointer to that object.
The pointer contains the following information:
.prefab, .mat, .png, .unity scene files, and .cs script files, has a corresponding .meta file that stores its GUID.GameObject instances with their own components. Each of these internal UnityEngine.Object instances has its own unique fileID within that single prefab file.Internally, Unity represents these references with a PPtr<T> type. When Unity loads these objects into memory at runtime, it resolves the GUID and fileID pair to an InstanceID, which it then uses to track the live object. The InstanceID is unique to the current Unity Editor session or runtime instance.
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:
{fileID: 0} means no object is referenced (equivalent to null in C#).{fileID: XXXX} contains only a fileID value. References another object within the same serialized file, such as a component referencing the GameObject it’s attached to.{fileID: XXXX, guid: YYYY, type: Z} contains a fileID, GUID, and type value. References an object in a different asset file.Open a scene file (.unity) or a prefab file (.prefab) in a text editor for an example of how Unity serializes these references. The following example shows a MonoBehaviour component in a scene file:
--- !u!114 &9394472
MonoBehaviour:
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 --- !u!114 &9394472 identifies this as a MonoBehaviour (class ID 114) with fileID 9394472 in this scene file. For more information about the YAML document structure, refer to Format of text serialized files.
This example contains all three reference formats:
m_CorrespondingSourceObject, m_PrefabInstance, and m_PrefabAsset use {fileID: 0} because this object is not part of a prefab instance.m_GameObject: {fileID: 9394470} points to the GameObject this component is attached to, which is another object in the same scene file with fileID 9394470.m_Script: {fileID: 11500000, guid: ..., type: 3} references the MonoScript asset for this component’s C# class. The GUID identifies the script’s .cs file, 11500000 identifies the MonoScript object inside that file, and type: 3 indicates an imported asset.sharedProfile: {fileID: 11400000, guid: ..., type: 2} references a Volume Profile stored as a ScriptableObject in a .asset file. The GUID identifies the asset file, 11400000 identifies the object inside that file, and type: 2 indicates a source asset that Unity reads directly.The type value in a cross-file reference tells Unity how to resolve the referenced asset’s file path from the GUID:
| Value | Name | Description | Examples |
|---|---|---|---|
0 |
NonAsset | Reference to a built-in resource or non-asset file. The GUID is a constant identifier (such as 0000000000000000e000000000000000 for Unity built-in resources) or null. |
Built-in primitive meshes, default shadersA program that runs on the GPU. More info See in Glossary, built-in extra resources. |
2 |
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 (.mat), ScriptableObject assets (.asset), AnimatorControllers (.controller). |
3 |
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 Library folder. |
ScriptsA piece of code that allows you to create your own Components, trigger game events, modify Component properties over time and respond to user input in any way you like. More info See in Glossary ( .cs), prefabs (.prefab), textures, 3D models, audio files. |
Note: Type 1 is a deprecated value from Unity 3.5 and earlier. Unity automatically upgrades type 1 references to type 3.
By default, Unity serializes any objects not derived from UnityEngine.Object 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.
You can use the [SerializeReference] 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.
You can’t use [SerializeReference] to reference a UnityEngine.Object-derived class. For more information, refer to Serialization rules.
When Unity loads assets and scenes into memory, it uses internal data structures to map references to live objects. These data structures include InstanceID, PPtr, Remapper, and PersistentManager. For UnityEngine.Object references, Unity maps the serialized GUID and fileID pairs to a live C++ Object. The C++ Object has a pointer to the associated C# UnityEngine.Object and finally, the C# object references back to the associated C++ object via the instance ID.
For [SerializeReference] objects, Unity maps managed reference IDs to live object instances. For details see ManagedReferenceUtility.GetManagedReferenceIdForObject.
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 UnityEngine.Object 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 GUID and fileID pairs) are included. This means careful management of direct references is crucial to prevent unused or unintentionally included assets.
For more information about the files Unity creates when it makes a build, refer to Content output of a build.
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 ScriptableObject instance to manage this. A ScriptableObject can hold direct references to other assets, which act as an asset catalog of references to your project’s assets. ScriptableObject 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.
You can also use AssetDatabase.FindAssets to find assets and populate a ScriptableObject with the data.