鳩の溜まり場

猫か鳩になりたい

Addressables Assets Systemでリソースのビルド用プロジェクトを用意して運用する【Unity】

はじめに

こちらはUnityゲーム開発者ギルド Advent Calendar 2022の19日目の記事です。

adventar.org

ふら~とAdventCalendarを見に来たらちょうど当日の枠が空いていたので急遽書くことにしてみました。

やること

別プロジェクトでビルドしたAddressables Assets System(AAS)のリソースをメインプロジェクトからロードする流れについてです。

対象としている読者

Addressablesの超基礎的な話は割愛します。

  • Addressablesを軽く使ったことがある
  • アドレスの登録/ロード程度しかやったことがない
  • リソースのビルド専用プロジェクトを用意したい
  • リソースをリモートに置いて利用したい

背景

AASでのビルドはプロジェクト自体に設定しているプラットフォームに向けてのみビルドするので、複数のプラットフォーム(AndroidiOS等)に向けたサービスの場合、ビルドするたびにBuild Settings -> Switch Platformをする必要があります。

その際、サービスそのものを開発しているプロジェクトでアセットをビルドするとなると、プラットフォームの切り替えにも時間がかかるため、無駄な時間が発生しがちです。

他にも、細かい懸念事項が出たりします。

  • エンジニア以外がアセットをビルドする際に関係のない個所を触ってしまうかもしれない
  • 組み込む予定のないアセットがあるのは気持ち悪い

理由はさておき、兎にも角にもリモートに配置するリソースは別プロジェクトで管理、ビルドしたい案件が起きた時の話です。

環境

  • Unity 2020.3.29f1
  • Addressables ver1.18.19

全体像

AASにはアドレスに対するリソースの情報や、リソース間の依存関係の情報等をまとめたカタログというものが存在します。
これはAASをビルドしたときに生成され、AASはリソースをロードする際にこのカタログの情報をもとにリソースのパス等を特定します。

つまり、このカタログとカタログに記されたリソースを用意すれば、あとはこのカタログの存在をAASに教えることでリソースをロードすることができるようになります。

これらを踏まえたうえで全体像を考えると、

  1. リソースのビルド用プロジェクトでリモートに配置するアセットをビルド
  2. アプリ用プロジェクトからリモートに配置してあるカタログを取得
  3. リソースのロードを行う

という流れになります。

ビルド用プロジェクトを作成

メインプロジェクトと同じバージョン、同じレンダリングパイプラインを搭載したプロジェクトを用意します。

今回は、Unityのバージョンを2020.3.29f1、レンダリングパイプラインはURPを選択しました。

プロジェクトが立ち上がったら、以下の手順で適当に準備します。

  1. PackageManagerからAddressablesをインストール
  2. Window -> Asset Managements -> Addressables -> Groupsを開く
  3. Create Addressables Settingsを押して設定回りのファイルを生成
  4. Default Local GroupはDefault Remote Group等適当な名前にしておく

グループの設定

Default Remote Groupを選択し、右クリックからInspect Group Settingsを選択します。

するとInspectorにDefault Remote Groupの設定ファイルの情報が表示されるので、各所設定します。
詳細については公式のマニュアルを参照していただき、ここでは別プロジェクトから扱う上で必要最低限の設定をします。

docs.unity3d.com

Content Update Restrictionの設定

Content Update Restrictionを設定します。
その名の通り、コンテンツを更新するときの制限の設定です。

ここではUpdate RestrictionをCan Change Post Releaseに設定します。

それぞれの違いは以下の通りです。

Can Change Post Release : ダウンロードコンテンツとして利用する際に新しいバージョンのコンテンツが存在したら自動で更新する
Cannot Change Post Release : プロジェクト自体をビルドしたタイミングでコンテンツが固定され以降更新できない

Content Packing & Loadingの設定

次にContent Packing & Loadingの設定です。
ここでは主にビルド時の出力先とAASがアセットをロードする際に参照するパスを設定します。

それぞれ以下のように設定します。

Build Path : Remote Build Path
Load Path : Remote Load Path

Build Pathはビルド時の出力先Load Pathはカタログに登録されるリソースのパスになります。

Remote Build PathやRemote Load Pathのパラメータの詳細はWindow -> Asset Managements -> Addressables -> Profilesから変更できます。
ここで指定されている[BuildTarget]等の変数は独自の静的プロパティを指定したりすることもできます。

Profiles | Addressables | 1.18.19

今回、Remote Build Pathはビルド用プロジェクトが存在する階層にserverというフォルダを用意してそこを指定し、Remote Load Pathはローカルサーバー直下を読むように指定しました。

Remote Build Path : ../server/[BuildTarget]
Remote Load Path : http://localhost:8000/[BuildTarget]

他にも高度な設定も出来ますが、ここでは必須ではないため扱いません。
AssetBundleの圧縮方法やキャッシュの利用の有無、バンドルにまとめる際の単位等を指定したりできます。
詳しくはAdvanced Optionsの公式マニュアルをご参照ください。

Group settings | Addressables | 1.18.19

Addressableシステムの設定

ここではAddressablesの基本的な設定情報が表示されるため、各所設定します。
グループの設定の時と同様、詳細については公式のマニュアルを参照していただき、ここでは別プロジェクトから扱う上で必要最低限の設定をします。

docs.unity3d.com

Addressables GroupsウィンドウのTools -> Inspect System Settingsを選択するとInspectorにAddressableシステムの設定項目が表示されます。

Catalogの設定

まず、カタログそのものに関わる設定です。

ここではPlayer Version Overrideを0.0.1にします。

通常、ビルド時にカタログが生成されると、カタログのファイル名はcatalog_{タイムスタンプ}.jsonになりますが、Player Version Overrideにパラメータを指定するとタイムスタンプの箇所が指定したものに置き換わります。
そのため、実際は0.0.1固定である必要はなく、各々好きなように設定していただいて大丈夫です。

Content Updateの設定

次に、リモートに配置するカタログ周りの設定です。

変更したパラメータは以下の通りです。

Build Remote Catalog : true
Build Path : Remote Build Path
Load Path : Remote Load Path

Build Remote Catalogをチェックを入れることでAddressablesのビルドを行ったタイミングでカタログも生成されるようになります。
(チェックを外すとプロジェクトのビルドを行うタイミングでカタログが生成されます。)

アセットを登録&ビルド&サーバーに配置

適当なオブジェクトをプレハブ化し、適当なアドレスを振ります。

ビルドしてRemote Buld Pathに設定したパスに以下の3つのファイルが存在するか確認します。

  • catalog_0.0.1.json
  • catalog_0.0.1.hash
  • defaultremotegroup_assets_all_xxxxxxxxxxx.bundle

*グループ名やカタログのバージョン名を違うものにした場合、各所自分の設定したものに置き換えて読んでください。

好きなやり方でローカルサーバーを立てます。

  1. $ cd {任意の場所}
  2. $ python -m http.server 8000

アプリ用プロジェクトでロードする

わかりやすいようにアプリ用のプロジェクトにも適当なアセットにアドレスを振っておきました。

アプリ用プロジェクトのAASにリモートのカタログを教える

アプリ用のプロジェクトは先ほどビルドしたカタログの存在は何も知らないため、明示的にカタログをAASに追加する必要があります。
新たなカタログは以下のメソッドでロードできます。

Addressables.LoadContentCatalogAsync(string catalogPath);

Addressables.LoadContentCatalogAsync | Addressables | 1.14.3

ロード

これらを踏まえたうえで簡易的なコードを用意しました。

public class AssetsLoader : MonoBehaviour
{
    // 追加するカタログ
    [SerializeField] private string catalogPath;
    // ロードするアセットのアドレス
    [SerializeField] private List<string> toLoadAssetAddressList;

    private async void Start()
    {
        // 追加のカタログをロード
        await Addressables.LoadContentCatalogAsync($"{catalogPath}").Task;

        // アセットを生成
        for (var i = 0; i < toLoadAssetAddressList.Count; i++)
        {
            var obj = await Addressables.InstantiateAsync(toLoadAssetAddressList[i]).Task;
            obj.transform.position = Vector3.right * i;
        }
    }
}

適当なシーン上にアタッチして、パラメータをよしなに設定します。

実行するとローカルとリモート両方にあるアセットをロード出来ていることがわかります。

補足1 catalog_XXX.hashについて

Addressablesのビルド時に生成されるcatalog_0.0.1.hashというファイルですが、これはカタログに差分があるか判別するためにAASが利用しているファイルになります。
中身はただのハッシュ値です。

c6375a11a7da704fe32ad078920d58a5

補足2 効率化用のエディタ拡張

マルチプラットフォームに向けて自動でAddressablesのビルドとプラットフォームの切り替えを行ってくれるエディタ拡張です。
ご自由にお使いください!

さいごに

急ぎで書いたので色々抜けてるところあるかもしれません!
もし間違い等ありましたらコメントにてご指摘いただけると幸いです。

今年1年ありがとうございました!メリクリ!🎄