こんにちは、Unityエンジニアのオオバです。

アセットバンドルに複数のアセットを格納して取り出す
アセットバンドル関連の続きになります。

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

以下はStreamingAssetsに格納されたAssetBundleをロードするサンプルコードです。

List abList = new Lists();  
IEnumerator Load (string name, System.Action 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 (name);  
 // 2.このタイミングでAssetBundleと取り出したアセットがメモリに積まれる  
 callback (obj);  
}

当たり前ですがロードされるとメモリに展開されます。
そして、var obj = ab.LoadAsset (name);この行でアセットバンドルからアセットを取り出され、それをcallbackの引数で返却するコードです。

予めabListにロードされたアセットバンドルは保持しておき、使い終わったらAssetBundleの破棄を試みます。

foreach (var ab in abList)  
 ab.Unload(true);  

Unload関数でアセットバンドルを破棄します。
よく見るとUnload関数の引数にはbool型を渡せます。

AssetBundle-Unload - Unity スクリプトリファレンス

リファレンスにもあるようにUnload関数の引数をfalseに設定するとロードしたAssetBundleのみがメモリから解放されます。

trueを選択するとLoadAssetで取り出したアセットもメモリから解放されてしまいます。

ただし、アセットを取り出した後、複製を行っていたらそれは対象外になるため注意が必要です。

コメントにも記載してあるように// 2.このタイミングでAssetBundleと取り出したアセットがメモリに積まれる、このタイミングではある意味重複したオブジェクトがメモリに乗っていることになります。ただAssetBundleは圧縮されているため、圧迫するメモリ量は違うことに注意です。

ちなみに、Unloadを実行したAssetBundleインスタンスはnullになる点も注意です。

オススメ記事
検証環境