mirror of
https://github.com/Donchitos/Claude-Code-Game-Studios.git
synced 2026-10-16 10:17:06 +00:00
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
8.0 KiB
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
Window > Package Manager- Unity Registry > Search "Addressables"
- 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
- Select asset in Project window
- Inspector > Check "Addressable"
- 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
Window > Asset Management > Addressables > Groups- 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
- Create new group:
Window > Addressables > Groups > Create New Group > Packed Assets - Group Settings:
- Build Path:
ServerData/[BuildTarget] - Load Path:
http://yourcdn.com/content/[BuildTarget]
- Build Path:
Build Remote Content
Window > Asset Management > Addressables > Build > New Build > Default Build Script- Upload
ServerData/folder to CDN - 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);