AssetBundleの管理の手間を大幅に省けるということで話題になったAddressable Assets Systemですが、Unite2018の大前さんの講演が非常にわかりやすく、それを元にしたブログ記事などもたくさんあり助かっています。しかし、Unity2019.4LTSで最新バージョンのものを使おうとしたら、いろいろ変更になっていて戸惑ったのでメモしておきます。
古い記事だと、manifestを手動で操作したり、Resource ManagerとAddressableをそれぞれインストールしたり、という手順がありますが、Unity2019.4では「Addressable」をPackage Managerからインストールするだけです。現在最新は1.10.0ですが、Unity2019.4 Verifiedになっている1.8.4をインストールしてみます。
1.8.4のドキュメントはこちら
インストールしたら、メニューのWindow > Asset Management > Addressables > Settingsを選択して設定ウインドウを開きます。
ここで、GeneralのSend Profiler Eventsにチェックを入れておきます。これで、Assetの利用状況がわかるAddressable Event Viewerが使えるようになります。
「Manage Groups」ボタンをクリックすると、Addressable Groupsウインドウが開きます。ここで各種アセットのグループへの登録と、「アドレス名」の設定ができます。
各種アセット(PrefabやTextureなど)を登録して「アドレス名」を設定すると、そのアセットがどこのAssetBundleに存在しても、「アドレス名」だけでそのアセットを呼び出すことができるようになります。デフォルトのグループはStreamingAssetsに配置したAssetBundleから呼び出されますが、ビルドの設定を変更してリモートのサーバから呼び出すこともできます。この時、コードの変更は必要ありません(「アドレス名」だけで追跡ができます)
アセットを登録するには、上記のAddressable Groupウインドウのグループ名(Default Local Groupなど)にアセットをドラッグ&ドロップするか、アセットのInspectorに表示される「Addressable」にチェックを入れてアドレス名を指定します。
デフォルトで入っているDefault Local Groupは、アプリのローカル(StreamingAssets)に配置したAssetBundleに格納する設定になっています。
ではこの状態で、Addressable GroupウインドウのメニューのBuild > New Build > Default Build Scriptを使ってAssetBundleをビルドしてみましょう。Addressableを使わないAssetBundleはビルドを自前のスクリプトで行う必要がありましたが、その必要はなくなりました。
ビルドを行うと、Library > com.unity.addressables の中にAssetBundleが生成されます。あれ、StreamingAssetsじゃなかったの?と思ってしまいますが、アプリをBuildするとちゃんとアプリ内のStreamingAssetsに配置されます。
では、Addressable化されてアドレス名を持ったアセットを呼び出す方法です。
using UnityEngine; using UnityEngine.AddressableAssets; public class Addressable : MonoBehaviour { void Start() { //アセットのロード Addressables.LoadAssetAsync<Sprite>("Hoge"); //アセットのインスタンス化 Addressables.InstantiateAsync("SnowMan"); } }
UnityEngine.AddressableAssets名前空間のAddressablesクラスを使って、アドレス名を直接指定することにより呼び出すことができます。ドキュメントではAsync operation handlingを使った方法も記載されています。メモリ管理を行う上では、こちらの方法を主に使うことになるでしょう。
また、AssetBundleと同じように、シーンを呼び出すこともできます。Build in Scneneに登録してなくても動作するので、ビルドの高速化が図れるのではないでしょうか。
Addressable化されたアセットは、従来のAssetBundle内のオブジェクトと異なり、静的に参照することができます。
AssetReference型のpublic変数を定義して、インスペクタからAddressable化されたアセットを指定すれば、ローカルにあるオブジェクトと同じように扱うことができます。これは画期的ですね。
using UnityEngine; using UnityEngine.AddressableAssets; public class Addressable : MonoBehaviour { [SerializeField] AssetReference assetReference; void Start() { assetReference.InstantiateAsync(); } }
AssetBundleを扱う時には、リリースを適切に行う必要がありました。AddressableはAssetBundle自体を扱う仕組みは隠蔽されていますが、同じくメモリ管理に気を使う必要があります。
参照の状態を表示するのに、古い記事ではRM Profilerを使用する、とありますが、現在はAddressables Event Viewerと名称が変わっています。
アドレス名を直接指定するのと、AssetReferenceで参照を持つ方法の比較考察です。
アプリを運用する時に、アプリ本体は極力更新しないで、AssetBundleだけを更新する、というケースがあります(主にスマホゲームなど)。この場合、AssetReferenceを使って参照を持つ、というやり方にすると、参照を持つのはアプリ本体なので、アプリ本体の更新が必要になってしまうと思われます。
なので、サーバからAPI経由で新しいアドレス名を取得し、そのアドレス名を使って、サーバ上にある新しいAssetBundleからアセットを呼び出す、という使い方になるのではないでしょうか(違っていたらTwitter等で教えてください!)
コメント
[…] Unity 2019.4 で使う Addressable Assets System | 独立型戦闘支援ブログ […]