Open4

Addressables導入メモ

ailail

準備

  • Unityの上部メニュー>PackageManager
  • UnityRegistryの項目を選択し、Addressablesを検索し、install
    • 2025/01/31時点でver2.2.2

導入

  • Unityの上部メニュー>Window>Asset Management>Addressables>Groupsを選択
  • Create Addressable Settingsのボタンが表示されたAddressable Groupsウィンドウが開くので、そのボタンをクリック
    • Assets/AddressableAssetsDataフォルダが作成され、諸々のデータが準備される

アセット登録

  • 同じAddressable Groupsウィンドウの表示のまま、このウィンドウにアセットをドラッグ&ドロップで登録するorアセットをProjectウィンドウでクリックしてInspectorを表示すると最上段に「Addressable」と記載されたチェックボックスが出現するので、それにチェックを入れる

パスを設定

  • Addressable Groupsではそれぞれのアセットを「特定のグループ」に所属している「アセット」という形で組み合わせた「グループ名/アセット名」というパスをつけることでそれぞれのアセットを一意に識別することを行う
  • そこで登録したアセット達に適切な「グループ名」と「アセット名」をつけてあげる必要がある
    • グループ名のデフォは「Default Local Group」
    • アセット名のデフォはProjectフォルダ上のAssetsフォルダを起点としたアセットへの相対パス(ディレクトリの区切りは/)
  • 例えば、Default Local Group→Itemsのように変更してみる
  • アセットの名称もちょっと長くなることが多くなるが、グループ名を右クリックして「Simplify Addressable Names」を選択すると相対パスからディレクトリ遷移を取り除いた純粋なファイル名のみに一発変換が可能

ラベルを設定

アセットには後述する取得や検索のためにラベルを割り振ることができる。ラベルはAddressable GroupsのLabel列で左クリックすると小窓が表示され、用意されたLabelの中から選択することで当該アセットにLabelを付けることができる。このLabelは「Manage Labels...」をクリックすることで、作成・削除が可能です。

このLabelはProjectウィンドウからアセットを選択し、Inspectorに表示されるAddressable関連項目からも設定可能。まとめてラベルをつけたいケースでは、Addressable GroupsウィンドウではなくてProjectウィンドウで同じラベルをつけたいアセットをまとめて選択し、Inspectorでラベル付けをまとめてやる手段がお手軽です。

ailail

Addressable Groupに格納したアセットを参照する方法

単純な取得

以下はAddresable Groupsに登録したappleというアセット名のSpriteを探し出すプログラム。Addressablesに関わる処理は基本的に非同期に行われる。

public Image image;
private AsyncOperationHandle<Sprite> spriteHandle;

public void Start() {
  Addressables.LoadAssetAsync<Sprite>("apple").Completed += handle => {
           if (handle.Result == null) {
               Debug.Log("Load Error");
               return;
           }
           image.sprite = handle.Result;
           //Addressables.Release(handle);
           spriteHandle = handle;
  };
}

public void OnDestroy()
{
          Addressables.Release(spriteHandle);
}

  • handleはAddressables内部で管理されているアセットへの参照情報でUnity(C#)のガベージコレクションの対象にならない。そのため、使い終わった参照情報はReleaseメソッドを実行して解放する必要がある。
  • Image型のimage変数に格納されたSpriteは参照情報を元に得られた画像アセットのコピー。このため、コピーを取られた時点でAddressablesの管理する「参照情報=handle」とは無関係になる
    • imageのspriteメンバーはUnityのシステムによる監視対象となるため、使われていないことがシステム的にわかるとガベージコレクションの対象になる
  • UnityEditorでのデバッグ中ではReleaseを行なってもなぜか参照が残るバグがある様子。勘違いするじゃん!!

部分一致

前述した単純な取得では完全一致("apple"の部分)でない場合、アセットの読み取りに失敗する。そこで、Addressableからアセットのロケーションの一覧を取得し、そのロケーションのパスから欲しいアセットを探す方法で対応するという荒技も可能。以下はItemsラベルのついたAddressable Groupsに登録されているSpriteアセットのロケーション一覧を取得し、keyで指定された文字列を含んだ最初のアセット(Sprite)を返却する非同期のメソッド。

public async Task<Sprite> GetSpriteDataAsync(string key)
    {
        List<IResourceLocation> locations = new List<IResourceLocation>();

        AsyncOperationHandle<IList<IResourceLocation>> handle = Addressables.LoadResourceLocationsAsync("Items", typeof(Sprite));
        await handle.Task;

        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            locations = handle.Result.Where(location => location.InternalId.Contains(key)).ToList();
            Addressables.Release(handle); // リストの複製を作成したので参照元は即不要
            if( locations.Count == 0 ) return null;
        }
        else
        {
            Debug.LogError(handle.OperationException.Message);
            Addressables.Release(handle);
            return null;
        }
        
        foreach (var location in locations)
        {
            Debug.Log("Location:"+location.InternalId);
            AsyncOperationHandle<Sprite> spriteHandle = Addressables.LoadAssetAsync<Sprite>(location);
            await spriteHandle.Task;

            if (spriteHandle.Status == AsyncOperationStatus.Succeeded)
            {
                Sprite result = spriteHandle.Result;
                // どこかで、Addressables.Release(spriteHandle);を忘れずに!
                return result;
            }
            else
            {
                Debug.LogError(spriteHandle.OperationException.Message);
                Addressables.Release(spriteHandle);
            }
        }

        return null; // 見つからなかった場合
    }

ailail

実行環境で動作させる

前述の解説までを通して、UnityEditor上ではAddressablesに登録したアセットを非同期で呼び出して、利用する方法は確認できた。Addressablesはここから、「Buildを行い、各種端末での実行においてAddressablesを動作させる」過程で行うべきこと、理解すべきことが多々存在する。

手っ取り早くで良いケース

Addressablesの高度な機能は特別に使わず、アセット群をもう初めからビルドに全て組み込むだけで良いのであれば以下を行う。

  • Addressables Groupsウィンドウを開き、
    • ウィンドウ右上にあるPlay Mode Scriptボタン>Use Asset Database(fastest)>Use Exsiting Build(・・・)に変更。・・・には、現在選択中のPlatformが表示される?
    • ウィンドウ右上にあるBuildボタン>New Build>Default Build Scriptをクリック(なお、この操作を行わない場合でもプロジェクト全体のBuild時に合わせて自動で行われます)

しっかりと構造を理解して活用するケース

割愛