ロバメモ - 素人のUnity覚書と奮闘記

素人のUnity覚書と奮闘記

Addressableを使ってみた

浦島太郎状態の私が、Addressableというパッケージを使えばアセットバンドルが楽に使えるらしいぜ!ってのを知ったので、試してみたの巻。
とりあえず、アセットバンドルを一つ作って、サーバーにあげて実機テストでゲーム画面に表示するまでをメモ。

パッケージをインストールする

Unity > Window > Package Manager でパッケージマネージャーを開く。
Unity Registryが選択されていることを確認して、虫眼鏡のマークのところで"addressable"を検索すると候補が出てくる。
f:id:nico-taniku:20210108115451p:plain:h400
Installボタンを押すとインストールが開始される。
AssetのPackageフォルダにAddressablesというフォルダが増えていれば成功。
f:id:nico-taniku:20210108115538p:plain:w300

AssetBundleとして使えるアセットの種類

・画像
・オーディオファイル
・フォント
・シーン
・プレハブ
・フォルダ

Adressを設定する

AssetBundleにしたいアセットをAssets内から選択して、そのInspectorを見ると、Addressableというチェックボックスの項目が増えているので、それにチェックを入れる。
自動的にAdressが設定される。変更することもできるけど、とりあえずそのままでOK。
f:id:nico-taniku:20210108140018p:plain:w500

注意点

対象ファイルがResourcesフォルダにある場合は、自動的にそこからResources_movedというフォルダに移動する。
設定前
f:id:nico-taniku:20210108140039p:plain:w300
設定後
f:id:nico-taniku:20210108140028p:plain:w300
任意の場所に移動させてOKだけど、Resourcesフォルダには入れないこと
Resoucesフォルダは、ビルドの時にシーン内に配置していなくても一緒に梱包したいファイルを置く場所。
ということは、AssetBundleにしたいファイルは、外部サーバー等からロードしたいので、Resoucesフォルダに入れないようにすること。

読み込みコードを書く

クラスを作って、適当なゲームオブジェクトにアタッチしておく。

サンプルコード(コルーチンを使って読み込み完了を待つ)

using System.Collections;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class LoadAsset : MonoBehaviour
{
    void Start()
    {
        StartCoroutine(Load());
    }

    IEnumerator Load()
    {
        //アセットのロード
        var handle = Addressables.LoadAssetAsync<GameObject>("TitleImage");
        yield return handle;
        //成功したらインスタンスを配置
        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            var instance = Instantiate(handle.Result);
        }
    }
}

使用するメソッド

使うのはこの非同期メソッド。 Addressables.LoadAsset(s)Async | Addressables | 1.15.1

Addressables.LoadAssetAsync<オブジェクトの型>("アドレス");
戻り値:AsyncOperationHandle<オブジェクトの型>
using :UnityEngine.AddressableAssets;

オブジェクトの型について

オブジェクトの型は、サンプルではプレハブを読み込むので<GameObject>になっているけど、画像なら<Image>、スプライトなら<Sprite>というふうに対象の型に合わせる。

引数について

引数のアドレスは、前項で設定したアドレス(↓)を記入する。Pathじゃないので注意。
[f:id:nico-taniku:20210108140018p:plain:w500]

戻り値について

AsyncOperationHandle<オブジェクトの型>は、構造体といわれるデータ型の一つらしい。
構造体の説明は割愛するけど、文字列などのデータ型を複数組み合わせてできたものって感じ。
これを使って、ロードの結果待ちをしたり、読み込んだオブジェクトを取得したりする。
使う際には、これ(↓)を追加しておくこと。

using UnityEngine.ResourceManagement.AsyncOperations;

ロードの完了を待つ方法

3通りあるようです。

・サンプルコードのようにコルーチンを使う方法
・AsyncOperationHandle.Completeイベントに完了後の処理を書いたメソッドを登録する方法
・AsyncOperationHandle.Taskでawaitを使って待つ方法

コルーチンを使う方法

サンプルのままだけど。個人的にコルーチンが使いやすいと思う。

void Start()
{
    StartCoroutine(Load());
}

IEnumerator Load()
{
    //アセットのロード
    var handle = Addressables.LoadAssetAsync<GameObject>("TitleImage");
    yield return handle;
    //成功したらインスタンスを配置
    if (handle.Status == AsyncOperationStatus.Succeeded)
    {
        var instance = Instantiate(handle.Result);
    }
}

AsyncOperationHandle.Completeイベントに完了後の処理を書いたメソッドを登録する方法

公式よりサンプルコード拝借&編集

private void Handle_Completed(AsyncOperationHandle<Gameobject> handle)
{
    if (handle.Status == AsyncOperationStatus.Succeeded)
    {
        var instance = Instantiate(handle.Result);
    }
}

void Start()
{
    var handle = Addressables.LoadAssetAsync<GameObject>("TitleImage");
    handle.Completed += Handle_Completed;
}

AsyncOperationHandle.Taskでawaitを使って待つ方法

公式よりサンプルコード拝借&編集

public async Start()
{
    var handle = Addressables.LoadAssetAsync<GameObject>("TitleImage");
    await handle.Task;
    if (handle.Status == AsyncOperationStatus.Succeeded)
    {
        var instance = Instantiate(handle.Result);
    }
}

Play Mode Script設定

Window > Asset Management > Addressables > Groupsを開く。
f:id:nico-taniku:20210108180417p:plain:w600
こんな画面が表示されるので、先ほどインスペクターでAddressableにチェック入れたアセットが表示されていると思う。
ここにあるPathは、チェックしたファイルがアセットのどこにあるかを示している。
Play Mode Scriptで、アセットをどこから読み込むかを設定できる。

Use Asset Database (fastest):高速モード
Unity内のアセットから読み込む。
Simulate Groups (Advanced):仮想モード
Unity内のアセットから読み込むのはfastestと同じで、アセットのload / unloadを管理する際のシミュレーションとして使うと便利らしい?ちょっと謎w
Use Existing Build(requires built groups):パックプレイモード
サーバー等からアセットバンドルを読み込む

使い分けとしては、Unityでテスト再生するときは高速モードか仮想モードで、実機テストや本番のビルドのときはパックプレイモードにする。

とりあえず、高速モードにして再生するとTitleImageが配置される。アセット内から読み込むのでビルドの必要がない。
サーバーから読み込みたい場合は、ビルドが必要になってくる。

サーバーアドレスの設定

AssetBundleをアップロードするサーバーのアドレスを設定する。
Window > Asset Management > Addressables > profilesを開く。
左側からグループを選ぶ(初期ならDefault)
一番下の項目[ RemoteLoadPath ]を、自分のサーバーのアドレスに変更する。ディレクトリで分けるならそれも含めてアドレス設定する。
最後の/[BuildTarget]は消さないように注意。
f:id:nico-taniku:20210108185927p:plain

AssetBundleのビルド方法を設定する

グループごとに、AssetBundleをどこに作る?ファイル名どうする?などを設定していく。
グループを選択 > 右クリック > Inspect Group Settings
f:id:nico-taniku:20210108191216p:plain:w400
インスペクターに設定画面が表示される。

いじるとしたら、この項目あたり。
f:id:nico-taniku:20210108191956p:plain:h700

Path設定

画像の上側の部分。
これは、サーバーアドレスの設定のところで設定した値を選ぶことになる。
サーバーから読み込みたいので、どちらもRemote〜のほうを選ぶ。
Build Path・・・アセットバンドルを作成する場所
Load Path・・・アセットバンドルをどこから読み込むのかを指定

その他設定

実はあんまり解ってないんだけどw
Bundle Mode・・・アセットバンドルの作成方法。個別・ラベル毎・ひとまとめの3択
Bundle Naming・・・AssetBundleの名前をどうつけるか選択する

AssetBundleをBuildする

Groups画面に戻って、Buildする。
f:id:nico-taniku:20210108194011p:plain
プロジェクトフォルダにServerDataフォルダが作成されて、そこにAssetBundleが作成されている。
f:id:nico-taniku:20210108194221p:plain:w500
これを、設定したサーバーにアップロードして、パックプレイモードで再生してアセットが表示されれば成功。
実機でテストもできる!
こやってプレイモードを切り替えるだけでテストと本番をスイッチできるのはありがたい。
あとは、複数読み込みたい場合などどうやって運営管理すればいいかを調べていかねば。

とりあえず今日のところは、以上なり。