渋谷ほととぎす通信

完全趣味でやってるUnityメモ。説明できないところを説明できるようにするための個人ブログ。昨日の自分より少しでも大きくなれるように。。。 ※所属団体とは一切関係がありません

アセットバンドルの破棄について


f:id:esakun:20150730215258g:plain

アセットバンドル関連の続きになります。

アセットバンドルのアンロード処理について調べておきます。

以下は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になる点も注意です。