UnityのAddressableアセットシステムでロード・アンロードする方法をまとめました。
Unity2019.2.10
Addressable1.3.8
はじめに
本記事ではAddressableアセットシステムを使ってロード・アンロードする方法をまとめます。
Addressableの概念や基礎知識についての説明はこの記事では省略しますが、
以下の記事にまとめていますので、必要に応じて参照してください。
基本的なロード方法と結果の待ち受け方
Addressableでは、Addressables.LoadAssetAsync()
にアドレスを指定することでアセットをロードできます。
Addressables.LoadAssetAsync<GameObject>("Example");
このメソッドはAsyncOperationHandle
構造体を返します。
結果を待ち受けるには、この構造体のCompletedでAsyncOperationHandle.Result
にアクセスします。
var handle = Addressables.LoadAssetAsync<GameObject>("Example"); handle.Completed += op => { if (op.Status == AsyncOperationStatus.Succeeded) { Instantiate(op.Result); } };
AsyncOperationHandle
構造体にはTaskも用意されているのでawaitで待ち受けることもできます。
var handle = Addressables.LoadAssetAsync<GameObject>("Example"); await handle.Task; if (handle.Status == AsyncOperationStatus.Succeeded) { Instantiate(handle.Result); }
また、下記のようにすればコルーチンで待ち受けることもできます。
var handle = Addressables.LoadAssetAsync<GameObject>("Example"); yield return handle; if (handle.Status == AsyncOperationStatus.Succeeded) { Instantiate(handle.Result); }
アセットをロードする
アセットをロードするには前節のようにAddressables.LoadAssetAsync()
を使います。
Addressables.LoadAssetAsync<GameObject>("Example");
参照カウントを減らすにはAddressables.Release()
にロードしたアセットか、AsyncOperationHandle
構造体を渡します。
また、シリアライズしたAssetReferenceからロードする方法もあります。
using UnityEngine; using UnityEngine.AddressableAssets; public class Example : MonoBehaviour { [SerializeField] private AssetReferenceGameObject _reference; private void Start() { _reference.LoadAssetAsync<GameObject>(); } }
この場合、Inspectorからアドレスを指定できます。
AssetReferenceでロードした場合、リリースは次のように行います。
_reference.ReleaseAsset();
ちなみにサブアセットをすべて取得したい場合は以下のようにします。
Addressables.LoadAssetAsync<IList<Mesh>>("FbxExample");
特定のサブアセットを取得したい場合には以下のように中括弧をつかいます。
Addressables.LoadAssetAsync<Mesh>("FbxExample[skin]");
Sceneをロードする
シーンをロードするにはAddressables.LoadSceneAsync()
を使います。
Addressables.LoadSceneAsync("ExampleScene");
Addressableを介さないシーン読み込みとは異なり、
Build Settingsにシーンを登録する必要はありません。
追加読み込みする場合には第二引数のLoadSceneModeをAdditiveにします。
Addressables.LoadSceneAsync("ExampleScene", UnityEngine.SceneManagement.LoadSceneMode.Additive);
シーンのアンロードをするにはAddressables.UnloadScene()
を使います。
引数にはロード時のAsyncOperationHandle
かSceneInstanceを渡します。
なお、LoadSceneMode.Single
でシーンを読み込んだ場合には古いシーンは自動的にアンロードされます。
GameObjectをロードしてInstantiateする
ここで、GameObjectをロードしてそのままInstantiateするようなケースを考えます。
var handle = Addressables.LoadAssetAsync<GameObject>("Example");
await handle.Task;
Instantiate(handle.Result);
このような場合、Addressables.InstantiateAsync()
を使うとロードだけでなくインスタンス化まで行ってくれます。
var handle = Addressables.InstantiateAsync("Example");
この方法の特徴として、このメソッドで生成したGameObjectは所属するシーンが破棄されたタイミングでReleaseされます。
また、Addressables.ReleaseInstance()
を使えば明示的にGameObjectの破棄と参照カウントのデクリメントをできます。
なおシーン切り替えでリリース済みのGameObjectに対してこれを呼んでもエラーにはなりませんでした。
ちなみにAssetReferenceGameObject
をつかってInstantiateすることもできます。
using UnityEngine; using UnityEngine.AddressableAssets; public class Example : MonoBehaviour { [SerializeField] private AssetReferenceGameObject _reference; private void Start() { _reference.InstantiateAsync(); } }