アセットバンドル関連の続きになります。
アセットバンドルのアンロード処理について調べておきます。
以下はStreamingAssetsに格納されたAssetBundleをロードするサンプルコードです。
※エラーハンドリングなどの処理は無し
List<AssetBundle> abList = new Lists<AssetBundle>(); IEnumerator Load<T> (string name, System.Action<T> callback) where T : Object { string path = Application.streamingAssetsPath + "/" + name; byte[] b = File.ReadAllBytes (path); var req = AssetBundle.LoadFromMemoryAsync (b); yield return req; // 1.このタイミングでAssetBundleがメモリに積まれる var ab = req.assetBundle; abList.Add(ab); var obj = ab.LoadAsset<T> (name); // 2.このタイミングでAssetBundleと取り出したアセットがメモリに積まれる callback (obj); }
当たり前ですがロードされるとメモリに展開されます。
そして、var obj = ab.LoadAsset<T> (name);
この行でアセットバンドルからアセットを取り出され、それをcallback
の引数で返却するコードです。
予めabListにロードされたアセットバンドルは保持しておき、使い終わったらAssetBundleの破棄を試みます。
foreach (var ab in abList) ab.Unload(true);
Unload関数でアセットバンドルを破棄します。
よく見るとUnload関数の引数にはbool型を渡せます。
Unity - スクリプトリファレンス: AssetBundle.Unload
リファレンスにもあるようにUnload関数の引数をfalse
に設定するとロードしたAssetBundleのみがメモリから解放されます。
true
を選択するとLoadAssetで取り出したアセットもメモリから解放されてしまいます。
ただし、アセットを取り出した後、複製を行っていたらそれは対象外
になるため注意が必要です。
コメントにも記載してあるように// 2.このタイミングでAssetBundleと取り出したアセットがメモリに積まれる
、このタイミングではある意味重複したオブジェクトがメモリに乗っていることになります。ただAssetBundleは圧縮されているため、圧迫するメモリ量は違うことに注意です。
ちなみに、Unloadを実行したAssetBundleインスタンスはnull
になる点も注意です。