はじめに
AssetBundleの処理の流れがモヤモヤしていたので少し調べてみました。 調査を行ったUnityのバージョンはUnity2021.3.13f1です。他のバージョンではここで記載した内容と異なっている可能性があります。 また、自分の調査に不備があり間違っている可能性もありますが、自己責任でお願いします。
AssetBundle.LoadFromFile
AssetBundle.LoadFromFileの処理のシーケンスは大まかには下記の通りでした。
- 圧縮されたままのAssetBundleファイル全体をヒープ上に読み込む
- リングバッファを経由してAssetBundleをヒープ上に解凍する(非圧縮の場合は未調査です)
- PersistentManagerに展開されたAssetBundleを登録する
これまで、Texture等の巨大なサイズのリソースはこのタイミング(LoadFromFile)ではメモリへ読み込まれていないのかなと淡い期待をもっていましたが、そいう訳ではありませんでした。(残念) また瞬間的には、圧縮されたままのAssetBundleと解凍された状態のAssetBundleの両方がヒープ上に置かれていることに注意して下さい。 また、ユーザーから見た時、AssetBundleファイルは色々なAssetを含んだファイルという印象ですが、システム的な観点からとらえるとAssetBundleファイルはストレージ(もしくはディスクイメージ)でCABファイルはストレージ内のディレクトリすると色々合点が行きます。ストレージ(AssetBundle)はLoadFromFileでマウンとして、Unloadでマウントしたストレージを取り出す訳です。
AssetBundle.LoadAsset
AssetBundle.LoadAssetは名前から、ファイルIDとパスIDを引き出して、ファイルIDからどのディレクトリ(CAB)に置かれている何番目のファイルかを求め、シリアライズデータを読み込みAssetを生成します。Assetがリソースの場合、resSファイルからストリームを読み込みます。(メモリーに乗っているので高速)
まとめ
個人的にはLoadFromFileではヘッダーおよびシリアライズファイル部分のみメモリーに読み込んで、サイズの大きいテクスチャ等が含まれてresSファイルは実際にAssetを読み込むAPIである、LoadAssetのタイミングでメモリーに乗ると思っていましたが以外でした。
以上