# Loadable<T>

> Serialized reference that loads a specific T asset from registered built content on demand instead of pulling it in with direct references.

## Definition

* **Type:** Class
* **Namespace:** [Unity.Loading](/engine/6000.7/script-reference/unity/loading.md)
* **Assembly:** UnityEngine.ContentLoadModule

```csharp
public sealed class Loadable<T> where T : Object
```

## Remarks

Add a [Loadable\<T>](/engine/6000.7/script-reference/unity/loading/loadable1.md) field to a [ScriptableObject](/engine/6000.7/script-reference/unityengine/scriptableobject.md) or [MonoBehaviour](/engine/6000.7/script-reference/unityengine/monobehaviour.md) to reference an asset without loading it immediately. The reference is stored as a [Loadable\<T>.LoadableObjectId](/engine/6000.7/script-reference/unity/loading/loadable1/loadableobjectid.md), which you create in the Editor with [LoadableObjectIdEditorUtility](/engine/6000.7/script-reference/unityeditor/loadableobjectideditorutility.md). When the containing object is built into a content directory with [BuildPipeline.BuildContentDirectory](/engine/6000.7/script-reference/unityeditor/buildpipeline/buildcontentdirectory.md), the referenced asset and its dependencies are pulled into the build output.

At runtime, call [Loadable\<T>.Load](/engine/6000.7/script-reference/unity/loading/loadable1/load.md) or [Loadable\<T>.LoadAsync](/engine/6000.7/script-reference/unity/loading/loadable1/loadasync.md) to load the asset on demand, read it from [Loadable\<T>.Target](/engine/6000.7/script-reference/unity/loading/loadable1/target.md), and call [Loadable\<T>.Release](/engine/6000.7/script-reference/unity/loading/loadable1/release.md) when it is no longer needed. The asset must belong to a content directory that has been registered with [ContentLoadManager.RegisterContentDirectory](/engine/6000.7/script-reference/unity/loading/contentloadmanager/registercontentdirectory.md).

In Play mode you can load built content with much the same code and behavior as in the Player. Register the content directory with [ContentLoadManager.RegisterContentDirectory](/engine/6000.7/script-reference/unity/loading/contentloadmanager/registercontentdirectory.md), get its root assets with [ContentLoadManager.GetRootAssets](/engine/6000.7/script-reference/unity/loading/contentloadmanager/getrootassets.md), then read the [Loadable\<T>](/engine/6000.7/script-reference/unity/loading/loadable1.md) fields on those root assets or on any asset or scene they reference. A [Loadable\<T>](/engine/6000.7/script-reference/unity/loading/loadable1.md) reached from built content always loads its asset from that built content, never from the project.

In Play mode you can also load the live project version of an asset, such as a scene loaded by path with [SceneManager.LoadSceneAsync](/engine/6000.7/script-reference/unityengine/scenemanagement/scenemanager/loadsceneasync.md) or a [ScriptableObject](/engine/6000.7/script-reference/unityengine/scriptableobject.md) loaded through [AssetDatabase](/engine/6000.7/script-reference/unityeditor/assetdatabase.md). A [Loadable\<T>](/engine/6000.7/script-reference/unity/loading/loadable1.md) field on an asset loaded this way always resolves to the latest project version of the referenced asset through the [AssetDatabase](/engine/6000.7/script-reference/unityeditor/assetdatabase.md), even when a registered content directory contains a built version of that asset.

Content loaded from the [AssetDatabase](/engine/6000.7/script-reference/unityeditor/assetdatabase.md) in this way is not reference counted, so [Loadable\<T>.Release](/engine/6000.7/script-reference/unity/loading/loadable1/release.md) does not unload it. It unloads through the same garbage collection that handles other AssetDatabase content in the Editor. The asset unloads when nothing references it and a collection runs. Call [Resources.UnloadUnusedAssets](/engine/6000.7/script-reference/unityengine/resources/unloadunusedassets.md) to force a collection.

A [Loadable\<T>](/engine/6000.7/script-reference/unity/loading/loadable1.md) field is only supported in content built with [BuildPipeline.BuildContentDirectory](/engine/6000.7/script-reference/unityeditor/buildpipeline/buildcontentdirectory.md). If a Loadable field is found in serialized data during a Player or AssetBundle build, the underlying reference is set to null in the build output and an error is logged. Suppress this error with [BuildOptions.SuppressLoadableErrors](/engine/6000.7/script-reference/unityeditor/buildoptions/suppressloadableerrors.md) for Player builds or [BuildAssetBundleOptions.SuppressLoadableErrors](/engine/6000.7/script-reference/unityeditor/buildassetbundleoptions/suppressloadableerrors.md) for AssetBundle builds.

Additional Resources: [Loadable\<T>.LoadableObjectId](/engine/6000.7/script-reference/unity/loading/loadable1/loadableobjectid.md), [LoadableObjectIdEditorUtility](/engine/6000.7/script-reference/unityeditor/loadableobjectideditorutility.md), [BuildPipeline.BuildContentDirectory](/engine/6000.7/script-reference/unityeditor/buildpipeline/buildcontentdirectory.md), [ContentLoadManager](/engine/6000.7/script-reference/unity/loading/contentloadmanager.md)

## Examples

```csharp
using Unity.Loading;
using UnityEngine;

namespace BuildDocExamples
{
    // Synchronous example: a MonoBehaviour that references a prefab through a Loadable<T>
    // field, loads and instantiates it on demand, and releases it when the component is destroyed.
    public class Loadable_LoadAndReleaseExample : MonoBehaviour
    {
        // Assign this in the Editor. The referenced prefab is pulled into the content
        // directory when this component's GameObject is built with BuildContentDirectory.
        public Loadable<GameObject> hatLoadable;

        private GameObject equippedHat;

        public void EquipHat()
        {
            // Guard against a missing reference: if the field was never assigned in the
            // Editor, or its id is invalid, there is nothing to load.
            if (hatLoadable == null || !hatLoadable.LoadableObjectId.IsValid)
                return;

            // Destroy any previously equipped hat before loading a new one, so repeated
            // calls don't leave old instances behind in the scene.
            if (equippedHat != null)
                Destroy(equippedHat);

            // Load() blocks until the prefab is available, then Target returns it.
            // Skip the load if this Loadable was already loaded by an earlier call, since
            // the operation is cached until Release().
            if (hatLoadable.Status != LoadableStatus.Loaded)
                hatLoadable.Load();
            if (hatLoadable.Target != null)
                equippedHat = Instantiate(hatLoadable.Target);
        }

        private void OnDestroy()
        {
            // These free two separate things:
            // Release() frees the loaded prefab asset that backs the Loadable,
            // while Destroy() frees the instance that Instantiate() spawned into the scene.
            hatLoadable.Release();
            Destroy(equippedHat);
        }
    }
}
```

```csharp
using Unity.Loading;
using UnityEngine;

namespace BuildDocExamples
{
    // Asynchronous example: a self-contained load -> use -> release flow. Loads an asset
    // through a Loadable<T> without blocking the main thread, uses it transiently, then
    // releases it in the same method. Because the whole lifecycle is contained here, this
    // method is safe to call repeatedly with the same Loadable.
    public class Loadable_LoadAndReleaseAsyncExample
    {
        // LoadAsync() returns an Awaitable that completes when loading finishes.
        // The content directory holding the asset must already be registered with
        // ContentLoadManager.RegisterContentDirectory before calling this.
        public async Awaitable LogIconSizeAsync(Loadable<Texture2D> icon)
        {
            // Await the load instead of blocking, so the game stays responsive while streaming.
            Texture2D texture = await icon.LoadAsync();

            // Use the asset transiently without retaining a reference to it, so it is safe
            // to release below. Reading a property is enough for this example.
            if (texture != null)
                Debug.Log($"Loaded icon is {texture.width}x{texture.height}.");

            // Release() completes the lifecycle: it frees the loaded asset and clears the
            // Loadable's cached load operation, so this method can be awaited again later.
            icon.Release();
        }
    }
}
```

## Constructors

| Constructor                                                                                                     | Description                                                   |
| --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------- |
| [Loadable\`1(Unity.Loading.LoadableObjectId@)](/engine/6000.7/script-reference/unity/loading/loadable1/ctor.md) | Creates a new Loadable with the specified loadable object id. |

## Properties

| Property                                                                                        | Description                                                                                                                                                                                                                                     |
| ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [LoadableObjectId](/engine/6000.7/script-reference/unity/loading/loadable1/loadableobjectid.md) | The underlying loadable object id.                                                                                                                                                                                                              |
| [Status](/engine/6000.7/script-reference/unity/loading/loadable1/status.md)                     | The current status of the loading operation.                                                                                                                                                                                                    |
| [Target](/engine/6000.7/script-reference/unity/loading/loadable1/target.md)                     | The result of the load operation. If the operation is not complete or has failed, this returns null. Use [Loadable\<T>.Load](/engine/6000.7/script-reference/unity/loading/loadable1/load.md) to force the operation to complete synchronously. |

## Methods

| Method                                                                            | Description                                                                                    |
| --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| [Load](/engine/6000.7/script-reference/unity/loading/loadable1/load.md)           | Loads the object synchronously. Blocks until loading is complete.                              |
| [LoadAsync](/engine/6000.7/script-reference/unity/loading/loadable1/loadasync.md) | Loads the object asynchronously. Returns an awaitable that completes when loading is finished. |
| [Release](/engine/6000.7/script-reference/unity/loading/loadable1/release.md)     | Releases the loaded object so that Unity can unload it.                                        |
| [ToString](/engine/6000.7/script-reference/unity/loading/loadable1/tostring.md)   | Returns a string representation of the loadable object id.                                     |
