Files
Claude-Code-Game-Studios/docs/engine-reference/unity/plugins/addressables.md
T
DonchitosandClaude Opus 5.5 b21fa0f7f2 Release 1.1.2 — the default path works end to end
Fix release for 1.1.1: the minimal path end to end, engine commands that
run on Godot, Unity and Unreal, hook warnings you can see, and verdicts
that say when they could not check. Details in CHANGELOG.md; upgrade
steps in UPGRADING.md (v1.1.1 → v1.1.2).

Fixes #67
Fixes #131

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
2026-09-29 21:32:19 +10:00

8.0 KiB

Unity 6.3 — Addressables

Last verified: 2026-02-13 Status: Production-Ready Package: com.unity.addressables (Package Manager)


Overview

Addressables is Unity's advanced asset management system that replaces Resources.Load() with async loading, remote content delivery, and better memory control.

Use Addressables for:

  • Async asset loading (non-blocking)
  • DLC and remote content
  • Memory optimization (load/unload on demand)
  • Asset dependency management
  • Large projects with many assets

DON'T use Addressables for:

  • Tiny projects (overhead not worth it)
  • Assets needed immediately at startup (use direct references)

Installation

Install via Package Manager

  1. Window > Package Manager
  2. Unity Registry > Search "Addressables"
  3. Install Addressables

Core Concepts

1. Addressable Assets

  • Assets marked as "Addressable" (assigned unique keys)
  • Can be loaded by key at runtime

2. Asset Groups

  • Organize assets (e.g., "UI", "Weapons", "Level1")
  • Groups determine build settings (local vs remote)

3. Async Loading

  • All loading is async (non-blocking)
  • Returns AsyncOperationHandle

4. Reference Counting

  • Addressables tracks asset usage
  • Must manually release assets when done

Setup

1. Mark Assets as Addressable

  1. Select asset in Project window
  2. Inspector > Check "Addressable"
  3. Assign key (e.g., "Enemies/Goblin")

OR via script:

#if UNITY_EDITOR
using UnityEditor.AddressableAssets;
using UnityEditor.AddressableAssets.Settings;

AddressableAssetSettings.AddAssetEntry(guid, "MyAssetKey", "Default Local Group");
#endif

2. Create Groups

Window > Asset Management > Addressables > Groups

  • Default Local Group: Bundled with build
  • Remote Group: Hosted on server (CDN)

Basic Loading

Load Asset Async

using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class AssetLoader : MonoBehaviour {
    async void Start() {
        // ✅ Load asset asynchronously
        AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>("Enemies/Goblin");
        await handle.Task;

        if (handle.Status == AsyncOperationStatus.Succeeded) {
            GameObject prefab = handle.Result;
            Instantiate(prefab);
        } else {
            Debug.LogError("Failed to load asset");
        }

        // ⚠️ IMPORTANT: Release when done
        Addressables.Release(handle);
    }
}

Load and Instantiate

async void SpawnEnemy() {
    // ✅ Load and instantiate in one step
    AsyncOperationHandle<GameObject> handle = Addressables.InstantiateAsync("Enemies/Goblin");
    await handle.Task;

    GameObject enemy = handle.Result;
    // Use enemy...

    // ✅ Release when destroying
    Addressables.ReleaseInstance(enemy);
}

Load Multiple Assets

async void LoadAllWeapons() {
    // Load all assets with label "Weapons"
    AsyncOperationHandle<IList<GameObject>> handle = Addressables.LoadAssetsAsync<GameObject>("Weapons", null);
    await handle.Task;

    foreach (var weapon in handle.Result) {
        Debug.Log($"Loaded: {weapon.name}");
    }

    Addressables.Release(handle);
}

Asset Labels (Tags)

Assign Labels

  1. Window > Asset Management > Addressables > Groups
  2. Select asset > Inspector > Labels > Add label (e.g., "Level1", "UI")

Load by Label

// Load all assets with label "Level1"
Addressables.LoadAssetsAsync<GameObject>("Level1", null);

Remote Content (DLC)

Setup Remote Groups

  1. Create new group: Window > Addressables > Groups > Create New Group > Packed Assets
  2. Group Settings:
    • Build Path: ServerData/[BuildTarget]
    • Load Path: http://yourcdn.com/content/[BuildTarget]

Build Remote Content

  1. Window > Asset Management > Addressables > Build > New Build > Default Build Script
  2. Upload ServerData/ folder to CDN
  3. Game loads assets from remote server

Preloading / Caching

Download Dependencies

async void PreloadLevel() {
    // Download all assets in group without loading into memory
    AsyncOperationHandle handle = Addressables.DownloadDependenciesAsync("Level1");
    await handle.Task;

    // Now "Level1" assets are cached, load instantly
    Addressables.Release(handle);
}

Check Download Size

async void CheckDownloadSize() {
    AsyncOperationHandle<long> handle = Addressables.GetDownloadSizeAsync("Level1");
    await handle.Task;

    long sizeInBytes = handle.Result;
    Debug.Log($"Download size: {sizeInBytes / (1024 * 1024)} MB");

    Addressables.Release(handle);
}

Memory Management

Release Assets

// ✅ Always release when done
Addressables.Release(handle);

// ✅ For instantiated objects
Addressables.ReleaseInstance(gameObject);

Check Reference Count

// Addressables uses reference counting
// Asset is unloaded when refCount == 0

Asset References (Inspector-Assigned)

Use AssetReference

using UnityEngine.AddressableAssets;

public class EnemySpawner : MonoBehaviour {
    // ✅ Assign in Inspector (drag & drop)
    public AssetReference enemyPrefab;

    async void SpawnEnemy() {
        AsyncOperationHandle<GameObject> handle = enemyPrefab.InstantiateAsync();
        await handle.Task;

        GameObject enemy = handle.Result;
        // Use enemy...

        enemyPrefab.ReleaseInstance(enemy);
    }
}

Scenes

Load Addressable Scene

using UnityEngine.SceneManagement;

async void LoadScene() {
    AsyncOperationHandle<SceneInstance> handle = Addressables.LoadSceneAsync("MainMenu", LoadSceneMode.Additive);
    await handle.Task;

    SceneInstance sceneInstance = handle.Result;
    // Scene loaded

    // Unload scene
    await Addressables.UnloadSceneAsync(handle).Task;
}

Common Patterns

Lazy Loading (Load on Demand)

Dictionary<string, AsyncOperationHandle<GameObject>> loadedAssets = new();

async Task<GameObject> GetAsset(string key) {
    if (!loadedAssets.ContainsKey(key)) {
        var handle = Addressables.LoadAssetAsync<GameObject>(key);
        await handle.Task;
        loadedAssets[key] = handle;
    }
    return loadedAssets[key].Result;
}

Cleanup on Scene Unload

void OnDestroy() {
    // Release all handles
    foreach (var handle in loadedAssets.Values) {
        Addressables.Release(handle);
    }
    loadedAssets.Clear();
}

Content Catalog Updates (Live Updates)

Check for Catalog Updates

async void CheckForUpdates() {
    AsyncOperationHandle<List<string>> handle = Addressables.CheckForCatalogUpdates();
    await handle.Task;

    if (handle.Result.Count > 0) {
        Debug.Log("Updates available");
        await Addressables.UpdateCatalogs(handle.Result).Task;
    }

    Addressables.Release(handle);
}

Performance Tips

  • Preload frequently used assets at startup
  • Release assets immediately when not needed
  • Use labels to batch-load related assets
  • Cache remote content for offline use

Debugging

Addressables Event Viewer

Window > Asset Management > Addressables > Event Viewer

  • Shows all load/release operations
  • Memory usage per asset
  • Reference counts

Addressables Profiler

Window > Asset Management > Addressables > Profiler

  • Real-time asset usage
  • Bundle loading stats

Migration from Resources

// ❌ OLD: Resources.Load (synchronous, blocks frame)
GameObject prefab = Resources.Load<GameObject>("Enemies/Goblin");

// ✅ NEW: Addressables (async, non-blocking) — keep the handle so it can be released
AsyncOperationHandle<GameObject> handle = Addressables.LoadAssetAsync<GameObject>("Enemies/Goblin");
GameObject prefab = await handle.Task;
// ... when the asset is no longer needed:
Addressables.Release(handle);

Sources