【Unity】AssetBundleのインクリメンタルビルドの仕組みと挙動

AssetBundleのインクリメンタルビルドの仕組み

Unity2019.2.10

インクリメンタルビルド?

AssetBundleのインクリメンタルビルドとは「変更のあったAssetBundleだけをビルドするための仕組み」です。

たとえば、いまAssetBundle AとAssetBundle Bをビルドしたとします。

f:id:halya_11:20191103143936p:plain

次にAssetBundle Aを構成するアセットだけに変更を加えて再度ビルドします。
この時、AssetBundle Bには変更が加わっていないため、
前回ビルドしたものが残っていればそれを使うことでビルドする必要がなくなります。

f:id:halya_11:20191103144057p:plain

このように変更が加わってものだけをビルドしてビルド時間を短縮する仕組みをインクリメンタルビルドといいます。

インクリメンタルビルドの仕組み

さてそれではUnityはどのようにこのインクリメンタルビルドを実現しているのでしょうか。

インクリメンタルビルドをするためには「更新されたかどうか」の判定をする必要があります。
UnityではこれをAssetFileHashとTypeTreeHashという二つのハッシュ値を使うことにより判定しています。
これらついて詳しくは以下の記事にまとめていますので必要に応じて参照してください。

light11.hatenadiary.com

これら二つのハッシュ値はAssetBundleをビルドする前に、そのAssetBundleを構成するアセットの情報から計算されます。
そしてそれらをビルド済みのAssetBundleのハッシュ値と比較します。
このハッシュ値は各AssetBundleがビルドした時に作られる、同名の.manifestファイルに書き込まれています。

このように、計算したハッシュ値と.manifestファイルのハッシュ値を比較して差分があればビルドを行い、なければビルドをスキップします。

f:id:halya_11:20191103144623p:plain

以上がインクリメンタルビルドの仕組みです。

挙動を確認する

次にインクリメンタルビルドの挙動を確認してみます。
まず下記のようにAssetBundle_AAssetBundle_BというPrefabを作ります。

f:id:halya_11:20191103224319p:plain

それぞれのPrefabには以下のようにAssetBundle名を設定しています。

Asset名 AssetBundle名
AssetBundle_A assetbundle_a
AssetBundle_B assetbundle_b

この状態でビルドすると二つのアセットバンドルとそのManifestファイルが生成されます。

f:id:halya_11:20191103224415p:plain

ここでAssetBundle_AのTransformに変更を加えて再びビルドしてみます。

f:id:halya_11:20191103224507p:plain

assetbundle_aの更新日時が変わり、AssetBundleが更新されていることが確認できました。

なお、AssetBundleのビルドにはAssetBundleBrowserを使っています。
これについては以下の記事で説明していますので、必要に応じて参照してください。

light11.hatenadiary.com

AssetBundleを消さずにManifestだけ消してみる

インクリメンタルビルドの挙動を確認するために、もう少し検証をしてみます。
まず、以下のようにAssetBundleを作っておきます。

f:id:halya_11:20191103224805p:plain

ここで、Manifestファイルだけを削除します。
そしてアセットには何も変更を加えず再ビルドを加えると下記のような結果となります。

f:id:halya_11:20191103224916p:plain

アセットには何も変更を加えていないにもかかわらずAssetBundleが再ビルドされました。
このように更新判定のためのハッシュ値が書かれているManifestファイルが消えると更新判定ができないのでビルドが走ります。

Manifestを消さずにAssetBundleだけ消してみる

次に、反対にManifestファイルは消さずにAssetBundleだけを消してみます。
最初はこんな感じです。

f:id:halya_11:20191103225332p:plain

この状態からManifestファイルだけを残してAssetBundleを削除します。

f:id:halya_11:20191103225350p:plain

次にAssetには更新を加えずにビルドを行うと以下のような結果となります。

f:id:halya_11:20191103225449p:plain

AssetBundleが消えたまま、再ビルドされませんでした。
AssetBundleの更新判定はあくまでManifestファイルのハッシュを見て行われるため、
今回はManifestを見てビルドをする必要がないと判断されたため、AssetBundleが消えたままになりました。

関連

light11.hatenadiary.com