Unity Addressables について
非同期ロード、グループ管理、メモリ管理、リモートコンテンツを必要とする開発者向けに、Unity Addressables によるアセット管理を解説するスキルです。Resources.Load からの移行や、メモリリークを防ぐハンドルの解放も扱います。
主な機能
- 01アセットの非同期ロード
- 02グループとラベルによる整理
- 03進捗付きアセットの先行ロード
- 04ハンドルと参照カウントの管理
- 05Addressables によるシーンロード
- 06Resources.Load からの移行
活用シーン
- 01Unity プロジェクトでアセットを必要時にロード
- 02任意コンテンツやシーン別コンテンツの管理
- 03ハンドル解放によるメモリリーク防止
- 04既存の Resources.Load 利用箇所を Addressables に移行
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ juliankerignard/ unity-skills --skill unity-addressablesインストール後、Claude Code で/unity-addressablesを入力して読み込まれたか確認します。
同梱ファイルreferences/addressables-patterns.md
詳細
Unity Addressables
このスキルでできること
非同期アセット読み込み、グループ構成、メモリ管理、リモートコンテンツ(CDN/DLC)に Addressables システムを使用する方法を説明します。Resources.Load からの移行、進捗表示付きのプリロード、参照カウント、メモリリークを防ぐための解放パターンについて解説します。
前提条件
- Package Manager からインストールしたパッケージ
com.unity.addressables
クイックスタート
- パッケージをインストールします:Window > Package Manager > Unity Registry > Addressables
- Window > Asset Management > Addressables > Groups を開きます
- アセットを「Addressable」としてマークします(Inspector のチェックボックス)
- 論理グループに整理します(機能別、シーン別、ダウンロード別)
Addressables.LoadAssetAsync<T>で読み込みます
判断フローチャート
Comment charger cet asset ?
|
+-- Toujours en memoire, reference directe dans l'Inspector ?
| --> Reference directe [SerializeField] (pas besoin d'Addressables)
|
+-- Charge a la demande, connu au compile-time ?
| --> AssetReference dans l'Inspector + LoadAssetAsync
|
+-- Charge dynamiquement par label/nom ?
| --> Addressables.LoadAssetsAsync avec label
|
+-- Contenu telechargeable (DLC, patches) ?
| --> Remote group + catalog update
|
+-- Migration depuis Resources.Load ?
--> Marquer les assets comme Addressable, remplacer Resources.Load par LoadAssetAsync
ステップバイステップガイド
Step 1:グループの構成
- 機能別グループ:
Characters、Levels、UI、Audio - ダウンロード別グループ:
Core(ビルドに含める)、Optional(ダウンロード可能) - シーン単位で読み込む場合はシーン別グループ
- 大きすぎるグループ(> 50 MB)は避け、用途別のサブグループに分割します
- ラベルを使って複数のグループにまたがるアセットにタグを付けます(
level1、boss、tutorial)
Step 2:ハンドルを使った非同期読み込み
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
public class AssetLoader : MonoBehaviour
{
[SerializeField] private AssetReference prefabRef;
private AsyncOperationHandle<GameObject> handle;
public async Awaitable<GameObject> LoadAndInstantiateAsync()
{
handle = Addressables.LoadAssetAsync<GameObject>(prefabRef);
await handle.Task;
if (handle.Status == AsyncOperationStatus.Succeeded)
return Instantiate(handle.Result);
Debug.LogError($"Failed to load: {prefabRef}");
return null;
}
private void OnDestroy()
{
// CRITIQUE: toujours release le handle
if (handle.IsValid())
Addressables.Release(handle);
}
}
重要なポイント:
- Inspector で
AssetReferenceを使うと、マジックストリングを避けられます await handle.Taskで読み込み完了を待ちますhandle.Resultを使用する前に、必ずhandle.Statusを確認します- メモリリークを防ぐため、
OnDestroyでReleaseを呼び出します
Step 3:ラベルによる読み込み
public class LabelLoader : MonoBehaviour
{
[SerializeField] private AssetLabelReference labelRef;
private AsyncOperationHandle<IList<GameObject>> handle;
public async Awaitable<IList<GameObject>> LoadAllAsync()
{
handle = Addressables.LoadAssetsAsync<GameObject>(labelRef, null);
await handle.Task;
if (handle.Status == AsyncOperationStatus.Succeeded)
return handle.Result;
Debug.LogError($"Failed to load label: {labelRef}");
return null;
}
private void OnDestroy()
{
if (handle.IsValid())
Addressables.Release(handle);
}
}
Step 4:Resources.Load から Addressables への移行
// AVANT (synchrone, tout en memoire au build)
var prefab = Resources.Load<GameObject>("Enemies/Goblin");
// APRES (async, charge a la demande)
var handle = Addressables.LoadAssetAsync<GameObject>("Enemies/Goblin");
await handle.Task;
var prefab = handle.Result;
// ... utiliser prefab ...
Addressables.Release(handle);
移行手順:
- アセットを
Resources/フォルダーの外に移動します - 各アセットを Addressable としてマークします(Inspector のチェックボックス)
- アドレスが以前の
Resources/パスと一致していることを確認します Resources.Load<T>(path)をAddressables.LoadAssetAsync<T>(address)に置き換えます- アセットが不要になったら
Release()を追加します - 移行が完了したら
Resources/フォルダーを削除します
Step 5:Addressables シーン
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.ResourceProviders;
public class SceneLoader : MonoBehaviour
{
[SerializeField] private AssetReference sceneRef;
private AsyncOperationHandle<SceneInstance> sceneHandle;
public async Awaitable LoadSceneAsync()
{
sceneHandle = Addressables.LoadSceneAsync(sceneRef);
await sceneHandle.Task;
}
public async Awaitable UnloadSceneAsync()
{
if (sceneHandle.IsValid())
{
await Addressables.UnloadSceneAsync(sceneHandle).Task;
}
}
}
厳守事項
- アセットが不要になったら、必ず
Addressables.Release(handle)を呼び出します - Inspector では必ず
AssetReferenceを使います(アドレスを文字列で直接指定しないでください) - 読み込み失敗を必ず処理します(
handle.Status) InstantiateAsyncで生成したオブジェクトには、Destroy()ではなく必ずAddressables.ReleaseInstance()を使います- 新規プロジェクトでは
Resources.Loadを絶対に使用しないでください(Addressables を使用します) - ハンドルを解放せずに保持することは絶対にしないでください(メモリリークの原因になります)
- 参照カウントを使わずに同じアセットを二度読み込むことは絶対にしないでください
- 参照の型を指定するには、
AssetReferenceT<T>(AssetReferenceGameObject、AssetReferenceSpriteなど)を優先して使用します - Inspector では、ラベル文字列よりも
AssetLabelReferenceを優先して使用します
関連スキル
/perf-audit:メモリリークと未解放アセットを検出します/unity-build-config:コンテンツとリモートカタログをビルドします/unity-code-gen:ローディングシステムとアセットマネージャーを生成します
トラブルシューティング
| 問題 | 解決策 |
|---|---|
| "InvalidKeyException" | アドレスまたはラベルが存在しません。Addressables Groups ウィンドウで確認してください |
| メモリリーク | Release() の呼び出し忘れです。Addressables Profiler(Event Viewer)を使用してください |
| ビルドにアセットが含まれない | アセットがどのグループにも属していないか、グループがビルドに含まれていません |
| 読み込みが遅い | グループが大きすぎます。用途別にサブグループに分割してください |
| "Cannot instantiate" | アセットがプレハブではないか、読み込みに失敗しています(Status を確認してください) |
| "Exception during init" | Addressables が初期化されていません。まず Addressables.InitializeAsync() を呼び出してください |
| アセットの重複 | 1 つのアセットが複数のグループに属しています。Build Report を使用して検出してください |
| リモートカタログが最新でない | 起動時に CheckForCatalogUpdates を呼び出し、その後 UpdateCatalogs を呼び出してください |
コメント
Markdown 対応