【Unity】Addressableを使って生成したGameObjectが破壊されたときにリソースを解放させるメモ

今週はメモ。
Addressableについて触れる機会があった。

MonoBehaviourを継承させたクラスを作り、
アセットハンドルを保持、OnDestroy時に破棄する処理を記述。

using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;

public class SelfRelease : MonoBehaviour
{
    //[Header("[SelfRelease]")]
    
    //-----------------------------------------------------------------------
    // メンバ変数
    //-----------------------------------------------------------------------

    /// <summary> 自信のアセットハンドル </summary>
    private AsyncOperationHandle m_handle;

    //-----------------------------------------------------------------------
    // Unityメゾット
    //-----------------------------------------------------------------------

    /// <summary> 破壊時処理 </summary>
    private void OnDestroy()
    {
        if(m_handle.IsValid())
        {
            Addressables.ReleaseInstance(m_handle);
        }
    }

    //-----------------------------------------------------------------------
    // 公開メゾット
    //-----------------------------------------------------------------------

    /// <summary> アセットハンドル登録 </summary>
    public void RegisterHandle(AsyncOperationHandle handle)
    {
        if(!m_handle.IsValid())
        {
            m_handle = handle;
        }
    }

} // class

スクリプトを作成し、以下のメゾットを記述。
GameObject生成時に上記で作成したコンポーネントを貼り付ける。 docs.unity3d.com

using System;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
using UnityEngine.ResourceManagement.ResourceProviders;
using NasanUtility.NasanDebug;

public static class N3Addressables
{
    //-----------------------------------------------------------------------
    // 公開メゾット
    //-----------------------------------------------------------------------

    /// <summary> GameObjectアセット生成したのちに自動リリースを行うコンポーネントを付与 </summary>
    /// <param name="key">ロードするキー</param>
    /// <param name="position">生成位置</param>
    /// <param name="rotation">生成回転地</param>
    /// <param name="loadedCallBack">生成後実行デリゲード</param>
    public static async void InitializeAsyncSelfRelease(AssetReferenceGameObject key, Vector3 position, Quaternion rotation, Action<GameObject> loadedCallBack = null)
    {
        var parameter = new InstantiationParameters(position, rotation, null);
        var handle = Addressables.InstantiateAsync(key, parameter);

        await handle.Task;

        if (handle.Status == AsyncOperationStatus.Succeeded)
        {
            handle.Result.AddComponent<SelfRelease>().RegisterHandle(handle);
            loadedCallBack?.Invoke(handle.Result);
        }
        else
        {
            N3Debug.LogError("InitializeAsyncSelfRelease Failed!!");
        }
    }
}

あとは、使用したいタイミングで作った関数を呼ぶ。

        [SerializeField]
        private AssetReferenceGameObject m_gameObject = null;

        private void Start()
        {
            N3Addressables.InitializeAsyncSelfRelease(m_gameObject, Vector3.zero, Quaternion.identity);
        }

参考にしたもの

Unity Addressable Asset system | Addressables | 1.10.0
GameObject-AddComponent - Unity スクリプトリファレンス