--- name: unity-addressables-design description: Source-anchored design rules for Unity Addressables 1.22.3/2.9.1 --- > **Before calling any skill in this module:** if you are about to call a skill with parameters guessed from its name or description, STOP — read this file (or fetch its schema via `GET /skills/recommend?includeSchema=true`) first. If you already have the parameter definitions from recommend/schema, you may proceed straight to dryRun. ## Triggers - Writing or reviewing Addressables code - Async asset/scene loading - Hot-update or catalog refresh - Version migration - 编写或审查 Addressables 代码、异步加载资源/场景、配置热更新或目录刷新、版本迁移 # Addressables - Design Rules Advisory module. Every rule is distilled from Unity Addressables source at two versions: - **1.22.3** — `com.unity.addressables@1.22.3` (Unity 2022, min 2019.4) - **2.9.1** — `com.unity.addressables@8460f1c9c927` (Unity 6, min 2023.1) Each rule cites a concrete file/line so the reasoning is auditable and the AI does not improvise against stale memory. > **Mode**: Documentation only — no REST skills to gate; load freely under any operating mode (Approval / Auto / Bypass). ## When to Load This Module Load before writing or reviewing any of: - `Addressables.InitializeAsync()` / `LoadContentCatalogAsync()` bootstrap code - `LoadAssetAsync` / `LoadAssetsAsync` / `InstantiateAsync` and their handle release - `LoadSceneAsync` / `UnloadSceneAsync` — especially with `SceneReleaseMode` (2.9.1) - `CheckForCatalogUpdates` → `UpdateCatalogs` → `CleanBundleCache` patch flow - `GetDownloadSizeAsync` / `DownloadDependenciesAsync` / `ClearDependencyCacheAsync` - `AssetReference` / `AssetReferenceT` field declarations and load/release - Any code that calls `WaitForCompletion()` or uses `AsyncOperationHandle` directly - Migration from 1.22.3 to 2.9.1 — removed APIs, changed overload signatures ## Version Difference Matrix | Area | 1.22.3 (Unity 2022) | 2.9.1 (Unity 6) | |------|---------------------|-----------------| | Non-Async variants (`LoadAsset`, `Instantiate`, `LoadScene`, etc.) | `[Obsolete]` — compile warning | **Removed** — compile error | | `IList` multi-key overloads | Present | Replaced by `IEnumerable` | | `SceneReleaseMode` enum | Does not exist | **New** — controls bundle lifetime on scene unload | | `LoadSceneAsync` `releaseMode` param | Absent | `SceneReleaseMode.ReleaseSceneWhenSceneUnloaded` default | | `LoadAssetsAsync(string key, ...)` | Does not exist | **New** string-key overload | | `UpdateCatalogs(bool autoCleanBundleCache, ...)` | Does not exist | **New** overload | | `LegacyResourcesLocator` / `LegacyResourcesProvider` | Present | **Removed** | | `DiagnosticEvent` / `DiagnosticEventCollector` | Present | **Removed** | | `ResourceManagerEventCollector` | Present | **Removed** | | `ResourceManager.RegisterDiagnosticCallback()` | `[Obsolete]` | **Removed** | | `InitializationOperation` property | `[Obsolete]`, returns `default` | **Removed** | | `BinaryCatalogInitializationData` | Does not exist | **New** | | `CachedFileProvider` | Does not exist | **New** | ## Critical Rule Summary | # | Rule | Version | Source anchor | |---|------|---------|---------------| | 1 | All non-Async variants (`LoadAsset`, `Instantiate`, `LoadScene`, `UnloadScene`, `GetDownloadSize`, `DownloadDependencies`, `Initialize`, `LoadContentCatalog`) are `[Obsolete]` in 1.22.3 and **removed** in 2.9.1. Always use the `*Async` form. | Both | `Addressables.cs:1.22.3:862-2226`, `Addressables.cs:2.9.1` (absent) | | 2 | Every `AsyncOperationHandle` returned by a Load/Instantiate call MUST be released via `Addressables.Release(handle)`. Forgetting leaks the AssetBundle in memory indefinitely — even after the scene unloads. | Both | `AsyncOperationHandle.cs:2.9.1:178-203` | | 3 | `WaitForCompletion()` blocks the calling thread synchronously. On WebGL it is **unsupported** and throws. Never call it on the main thread in production; use `await handle.Task` or the `Completed` event instead. | Both | `AsyncOperationHandle.cs:2.9.1:178-203` | | 4 | `LoadSceneAsync` in 2.9.1 adds `SceneReleaseMode releaseMode` (default `ReleaseSceneWhenSceneUnloaded`). If a Single-mode load unloads your additive scene and you need the bundle to stay alive, pass `OnlyReleaseSceneOnHandleRelease` and release the handle manually. | 2.9.1 | `ISceneProvider.cs:2.9.1:14-26`, `Addressables.cs:2.9.1:1914` | | 5 | Multi-key overloads changed from `IList` to `IEnumerable` in 2.9.1. The old `IList` overloads no longer exist — pass `IEnumerable` or `string[]`. | 2.9.1 | `Addressables.cs:2.9.1:1148,1566,1636` | | 6 | `LegacyResourcesLocator` and `LegacyResourcesProvider` were removed in 2.9.1. Do not reference them in code targeting Unity 6. | 2.9.1 | `Runtime/ResourceLocators/` (absent in 2.9.1) | | 7 | `ResourceManager.RegisterDiagnosticCallback()` was `[Obsolete]` in 1.22.3 and removed in 2.9.1. Use the Addressables Profiler window instead. | 2.9.1 | `ResourceManager.cs:1.22.3:353` (absent in 2.9.1) | | 8 | Catalog update flow is strictly ordered: `CheckForCatalogUpdates → UpdateCatalogs`. In 2.9.1, `UpdateCatalogs(bool autoCleanBundleCache, ...)` can auto-clean stale bundles in one call. | Both | `Addressables.cs:2.9.1:2092-2147` | | 9 | `AssetReference.LoadAssetAsync()` returns a handle that must be released via `assetRef.ReleaseAsset()`, NOT `Addressables.Release(handle)`. Mixing the two causes double-release exceptions. | Both | `AssetReference.cs:1.22.3:44-46` | | 10 | `InitializationOperation` property (1.22.3) is `[Obsolete]` and returns `default`. Do not await it. Use `await Addressables.InitializeAsync()` instead. | 1.22.3 | `Addressables.cs:1.22.3:981-982` | ## Sub-doc Routing | Sub-doc | When to read | |---------|--------------| | [INIT.md](./INIT.md) | `InitializeAsync` / `LoadContentCatalogAsync` / catalog loading order / `autoReleaseHandle` semantics | | [HANDLES.md](./HANDLES.md) | `AsyncOperationHandle` lifecycle — `Completed`, `WaitForCompletion`, `Release`, `IsDone`, `Status`, `OperationException`, ref-counting | | [LOADING.md](./LOADING.md) | `LoadAssetAsync`, `LoadAssetsAsync` (all overloads + version diff), `MergeMode`, `InstantiateAsync`, `ReleaseInstance` | | [SCENE.md](./SCENE.md) | `LoadSceneAsync` / `UnloadSceneAsync` / `SceneInstance.ActivateAsync` / `SceneReleaseMode` (2.9.1) / `activateOnLoad=false` pattern | | [UPDATE.md](./UPDATE.md) | `CheckForCatalogUpdates` → `UpdateCatalogs` flow / `autoCleanBundleCache` (2.9.1) / `CleanBundleCache` / `ResourceLocatorInfo` | | [DOWNLOAD.md](./DOWNLOAD.md) | `GetDownloadSizeAsync` / `DownloadDependenciesAsync` / `ClearDependencyCacheAsync` / `DownloadStatus` struct | | [ASSETREF.md](./ASSETREF.md) | `AssetReference` / `AssetReferenceT` / `LoadAssetAsync` / `ReleaseAsset` / `OperationHandle` property / `IsDone` guard | | [PITFALLS.md](./PITFALLS.md) | 30 concrete hallucination pitfalls with version tags + legacy API migration section | ## Routing to Other Modules - Asmdef layout for Addressables consumers → load [asmdef](../asmdef/SKILL.md) - Async orchestration across multiple Addressables operations → load [async](../async/SKILL.md) - Architecture-level decisions (Addressables vs YooAsset, group strategy) → load [architecture](../architecture/SKILL.md) - Performance review of load/release hot paths → load [performance](../performance/SKILL.md) ## Version Scope This document targets two versions: - **1.22.3** — shipped with Unity 2022 LTS. Contains `[Obsolete]` non-Async variants still present for migration. - **2.9.1** — shipped with Unity 6 (2023.1+). All `[Obsolete]` APIs removed. New `SceneReleaseMode`, binary catalog format, `AutoGroupGenerator`. When a rule applies to only one version it is tagged `[1.22.3]` or `[2.9.1]`. Untagged rules apply to both. ## Migration Notes (hallucination shield) | Legacy API | Status | Replacement | Source | |------------|--------|-------------|--------| | `Addressables.Initialize()` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | `Addressables.InitializeAsync()` | `Addressables.cs:1.22.3:862-864` | | `Addressables.LoadAsset(key)` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | `Addressables.LoadAssetAsync(key)` | `Addressables.cs:1.22.3:992-1007` | | `Addressables.LoadAssets(keys, cb, mode)` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | `Addressables.LoadAssetsAsync(keys, cb, mode)` | `Addressables.cs:1.22.3:1242-1276` | | `Addressables.Instantiate(key, ...)` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | `Addressables.InstantiateAsync(key, ...)` | `Addressables.cs:1.22.3:1892-1972` | | `Addressables.LoadScene(key, ...)` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | `Addressables.LoadSceneAsync(key, ...)` | `Addressables.cs:1.22.3:2090-2106` | | `Addressables.UnloadScene(handle, ...)` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | `Addressables.UnloadSceneAsync(handle, ...)` | `Addressables.cs:1.22.3:2180-2226` | | `Addressables.GetDownloadSize(key)` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | `Addressables.GetDownloadSizeAsync(key)` | `Addressables.cs:1.22.3:1547` | | `Addressables.DownloadDependencies(key)` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | `Addressables.DownloadDependenciesAsync(key)` | `Addressables.cs:1.22.3:1608` | | `Addressables.InitializationOperation` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | `await Addressables.InitializeAsync()` | `Addressables.cs:1.22.3:981-982` | | `LoadResourceLocationsAsync(IList keys, ...)` | Present in 1.22.3, **removed** in 2.9.1 | `LoadResourceLocationsAsync(IEnumerable keys, ...)` | `Addressables.cs:2.9.1:1148` | | `GetDownloadSizeAsync(IList keys)` | Present in 1.22.3, **removed** in 2.9.1 | `GetDownloadSizeAsync(IEnumerable keys)` | `Addressables.cs:2.9.1:1566` | | `DownloadDependenciesAsync(IList keys, mode, ...)` | Present in 1.22.3, **removed** in 2.9.1 | `DownloadDependenciesAsync(IEnumerable keys, mode, ...)` | `Addressables.cs:2.9.1:1636` | | `LegacyResourcesLocator` / `LegacyResourcesProvider` | Present in 1.22.3, **removed** in 2.9.1 | Use Addressables groups for all assets | `Runtime/ResourceLocators/LegacyResourcesLocator.cs:1.22.3` | | `ResourceManager.RegisterDiagnosticCallback(...)` | `[Obsolete]` in 1.22.3, **removed** in 2.9.1 | Addressables Profiler window | `ResourceManager.cs:1.22.3:353` | | `DiagnosticEvent` / `DiagnosticEventCollector` | Present in 1.22.3, **removed** in 2.9.1 | Addressables Profiler / custom IProfilerEmitter | `Runtime/ResourceManager/Diagnostics/:1.22.3` | When in doubt, read the cited source — not your memory.