見出し画像

UnityのAddressablesと仲良くなる

コード書いとる?

UnityプロジェクトにAddressablesを導入したのでメモ書き。ここはnote。

Prefabで困る事もある

「Prefabにしたらいいんじゃない?」一時期そう考えている自分がいました。ですが...シーン内のGameObjectから強参照しているPrefabは全てメモリに展開されるという仕様を拝見して顔面蒼白になりました(盛りすぎ)

参考資料
https://blog.unity.com/ja/technology/tales-from-the-optimization-trenches-saving-memory-with-addressables

ぶっちゃけこういうのはメモリ効率的にはアカンという事です。シーン開始時に全てメモリにInstantiateされとるんです。

public class Hoge : MonoBehaviour
{
    public GameObject[] fugaPrefabs;
}

必要なPrefabだけ欲しい。

こういう仕様があるなら...Instantiateするまでは大人しくしてて欲しいと思うのが人情というものじゃないですか!全部メモリに展開されるのかよ!と思ったらありました!Addressablesです!

使い方は...Package Managerから導入して、適当にDefault Addressable Groupを作ってPrefabを組み込みます。ここまでは特に困らないでしょう。Default Local Groupをに必要なPrefabを追加できればOK。アプリビルド時にAddressableも組み込まれます。

こんな感じ

そして公式マニュアルにざっくりと目を通してください。https://docs.unity3d.com/Packages/com.unity.addressables@1.21/manual/index.html

Prefab読み込み

自分が好むのはファイル名を単純化した識別子で読み込む手法です。非同期処理は苦手なので読み込み完了コールバックを使っています。

var loadHandle = Addressables.LoadAssetAsync<GameObject>("path to prefab");
loadHandle.Completed += (handle) =>
{
    var obj = Instantiate(handle.Result);
    // 以下適当な処理
    // GameObjectを使い終わったらhandleをReleaseする
    // Addressables.Release(handle);
};

パスの有効判定

パスの有効判定はちょっとめんどい。ネットワーク越しのAddressablesにも対応してるからきっと周りくどい方法になりますよねー。知らんけど。って感じです。

var handle = Addressables.LoadResourceLocationsAsync("path to prefab");
handle.Completed += (hdl) =>
{
    if (hdl.Status == AsyncOperationStatus.Succeeded
        && hdl.Result.Any())
    {
        // アセット読み込み
        var loadHandle = Addressables.LoadAssetAsync<GameObject>("path to prefab");
        loadHandle.Completed += (handle) =>
        {
            // Prefabの読み込み処理
        };
    }
    Addressables.Release(hdl);
};

C#なんだけどReleaseは手動です。C#なんだけどね!

スッキリ!!

いいなと思ったら応援しよう!