はなちるのマイノート

Unityをメインとした技術ブログ。自分らしくまったりやっていきたいと思いますー!

【Unity】ローカルで利用するAddressable Asset Systemの基本的な使い方

概要

Addressable Asset Systemとはアドレスを用いてアセット(例. プレハブ、テクスチャ、マテリアル、オーディオクリップ、アニメーション)を簡単にロードできる機能になります。

The Addressable Asset System provides an easy way to load assets by “address”. It handles asset management overhead by simplifying content pack creation and deployment.

Addressable Assets Overview | Package Manager UI website

環境

Unity 2020.3.18f1
Addressable 1.18.19

インストール

PackageManagerによりインストールを行います。
※ Unity 2018.2 or later

f:id:hanaaaaaachiru:20220320195148p:plain
Addressable Asset System

Addressable Assetとしてマークをする

Addressable Assetとしてマークをつけると、Addressable Asset Systemを用いて、まさにResourcesフォルダに入っているアセットをResources.Loadを読み込むように、どこからでも呼び出せるようになります。

このAddressable Assetとしてマークをつける手法は以下の二つがあります。

対象アセットのインスペクターによるマーク

対象アセットのインスペクターの上の方にAddressableというボタンが追加されていると思うので、そちらにチェックマークをつければOKです。

f:id:hanaaaaaachiru:20220320200257p:plain
Addressable Assetとしてのマークする1

Addressable Windowにてマーク

メニューバーよりWindow -> Asset Management -> Addressables -> Groupを選択し、Addressables Groups Windowを開きます。

f:id:hanaaaaaachiru:20220320201026p:plain
Addressables Groups Window

Addressable AssetとしてマークしたいアセットをAddressables Groups Windowにドラッグ&ドロップすればマーク完了です。

f:id:hanaaaaaachiru:20220320201345p:plain
Addressable Assetとしてのマークする2
フォルダごとマークする

フォルダ毎ドラッグ&ドロップしてあげると、フォルダの中に入っているアセットを一気に登録することができます。

f:id:hanaaaaaachiru:20220320212856p:plain
フォルダ毎マーク

またフォルダ内のアドレスが固定になることに注意してください。(フォルダのアドレス/〇〇)

Addressの変更

Addressable Assetに割り当てられているAddressはデフォルトではAssets/Sprites/a.pngのようにAssetsからの相対パスが入力されます。

ただしこの形でなければならないというわけではなく、一意であれば大丈夫なので自由に変更することができます。
※必ず一意でなければならないというわけではなく、同じアドレスに設定は一応できるみたいです。ただ思わぬバグの発生の元だと思うので非推奨。

f:id:hanaaaaaachiru:20220320202432p:plain
Addressの変更

Assetをロードする

基本はAddressables.LoadAssetAsyncAddressables.InstantiateAsyncを利用します。
Class Addressables | Package Manager UI website

private async void Start()
{
    // Spriteをロード
    var sprite = await Addressables.LoadAssetAsync<Sprite>("Assets/Sprites/a.png").Task;
        
    // ロードに失敗しても、Debug.LogErrorに表示されるだけで、エラーにはならない模様
    var sprite2 = await Addressables.LoadAssetAsync<Sprite>("hoge").Task;
    if (sprite2 == default)
    {
        // defaultであれば、ロードに失敗している
        Debug.LogError("ロードに失敗しました");
    }
        
    // 使い終わったらメモリから開放する
    Addressables.Release(sprite);

    // GameObjectをInstantiateする場合は以下のメソッドを利用すると良い
    // LoadAssetAsyncをした時とメモリ管理の挙動がことなるので注意
    // 参考 : https://light11.hatenadiary.com/entry/2020/01/04/193512
    var gameObject = await Addressables.InstantiateAsync("Sample.prefab").Task;

    // 使い終わったらゲームオブジェクトと共にメモリから削除する
    Addressables.ReleaseInstance(gameObject);

    // 以下のコードでゲームオブジェクトを削除するとメモリリークするので注意(Addressables Event Viewerで確認済)
    // Destroy(gameObject);
}

またAddressable Asset Systemでメモリに読み込んだアセットは、明示的に開放しなくてはいけないことに注意してください。

具体的にはAddressables.ReleaseAddressables.ReleaseInstanceですね。

加えてAddressable.Releaseの引数はAsyncOperationHandleでなければいけないのかなと最初は思ったのですが、上記のコードでも正しく開放ができているようです。(Addressable Event Viewerにより確認)

// Spriteをロード
AsyncOperationHandle<Sprite> handle = Addressables.LoadAssetAsync<Sprite>("Assets/Sprites/a.png");
await handle.Task;
if (handle.Status == AsyncOperationStatus.Succeeded)
{
    // ロード成功
    Sprite sprite = handle.Result;
            
    // 開放する
    Addressables.Release(handle);
}
f:id:hanaaaaaachiru:20220320214332p:plain
Addressables Event Viewer

Assetをロードする(AssetReferenceを利用する)

AssetReferenceを利用することで、アドレスの文字列を知らずともAssetをロードすることができます。
Class AssetReference | Package Manager UI website

// Sprite用のAssetReference
[SerializeField] private AssetReferenceSprite spriteReference;
// GameObject用のAssetReference
[SerializeField] private AssetReferenceGameObject gameObjectReference;
    
private async void Start()
{
    // Spriteをロードする
    var sprite = await spriteReference.LoadAssetAsync<Sprite>().Task;

    // 使い終わったらメモリから開放する
    spriteReference.ReleaseAsset();
        
    // ゲームオブジェクトをインスタンス化する
    var gameObject = await gameObjectReference.InstantiateAsync().Task;
        
    // 使い終わったらメモリから解放する
    gameObjectReference.ReleaseInstance(gameObject);
}
f:id:hanaaaaaachiru:20220320210849p:plain
AssetReference

AssetReference〇〇はいくつか種類があるみたいなので、適したものを見つけてあげてください。
Class AssetReference | Package Manager UI website

アセットバンドルを作成する

Addressable Groups WindowPlay Mode Scriptを押すと、Play Modeというアセットの読み方の手法を設定することができます。

f:id:hanaaaaaachiru:20220321001112p:plain
Play Mode


Use Asset DatabaseSimulate Groupsの場合はエディタ上ではAsset Databaseを利用してアセットをロードするためアセットバンドルを作成する必要はありません。

しかし実機ビルドをする場合やUse Existing Buildの場合は、Addressable Assetsからアセットバンドルをビルドする必要があります。

f:id:hanaaaaaachiru:20220321001914p:plain
公式ドキュメントより引用

Addressable Assets development | Package Manager UI website
※名前が変わっているようなので注意

バンドルを作成するには、Addressable Group WindowにてBuild -> New Build -> Default Build Scriptを選択すれば完了です。

f:id:hanaaaaaachiru:20220321000320p:plain
ビルド