【Unity】【Addressable】ダウンロードコンテンツを更新するときにはメモリを綺麗にするかUnique Bundle IDを使う

UnityのAddressableアセットシステムでダウンロードコンテンツを更新するときに気を付けるべきこととUnique Bundle IDという機能についてまとめます。

Addressables 1.8.5

起動中にダウンロードコンテンツを更新したい

いま、アプリの起動中にダウンロードコンテンツの更新があった時のことを考えます。
アプリを起動しているのですでにメモリ上に読み込み済みのリソースが存在し、今回更新したいリソースもその読み込み済みのものであるとします。

f:id:halya_11:20201223223433p:plain
ロード済みのリソースを更新

このとき、ダウンロードしてストレージのリソースを更新することは簡単ですが、
メモリにはすでに古いリソースが乗っているのでユーザから見えるリソースは更新されません。

f:id:halya_11:20201223223812p:plain
メモリは更新されない

本記事ではAddressableアセットシステムにおいてこのようなケースをどのように取り扱えばいいかをまとめます。

アンロードしてからロードするという正攻法

一つ目のスタンダードな方法としてメモリ上のリソースを一度アンロードするという方法があります。
アンロードしてダウンロード済みの新しいリソースをロードしなおします。

f:id:halya_11:20201223224121p:plain
アンロードしてからロード

Unique Bundle IDという機能

もう一つ、Addressable独自の方法としてUnique Bundle IDという機能があります。

そもそもUnityがロード済みのアセットバンドルを更新できない理由として、「同じ名前を持つアセットバンドルを同時に二つロードできない」という点があります。
Unique Bundle IDを使うと、同じアセットバンドルを更新した際に内部的に別の名前(ID)を割り振って古いアセットバンドルと同時にロードできるようにします。

f:id:halya_11:20201223225221p:plain
同名アセットバンドルを同時にロード

この仕組みを使って更新のときに新しいアセットバンドルを同時に読み込むことでアンロードを挟まずに更新を実現します。
この機能はデフォルトでオフになっています(正確には一時期のバージョンではデフォルトONになっていましたが次節のデメリットがあるのでオフになった)。
オンにするにはAddressable Asset SettingsのUnique Bundle IDにチェックを入れます。

f:id:halya_11:20201223225637p:plain
Unique Bundle ID

Unique Bundle IDのデメリット

さて一見便利そうなUnique Bundle IDですがデメリットもあります。
それを説明するために以下のようにPrefabとそれが参照するMaterialを考えます。

f:id:halya_11:20201223230136p:plain
PrefabとMaterial

ここでMaterialを更新してアセットバンドルをビルドしなおしたとします。
PrefabとMaterialはそれぞれ別のアセットバンドルに含まれているので、ここではMaterialのアセットバンドルだけを更新すれば済むはずです。
しかしUnique Bundle IDを使うと、依存関係ごと更新をしなければいけないためPrefabのアセットバンドルにまで再ビルドされてしまいます。

f:id:halya_11:20201223230556p:plain
Prefabまでリビルド

再ビルドされるということはそれだけユーザがダウンロードしなければならないリソースも増えるということです。
このデメリットを考えると、依存関係が複雑で更新が多いような大規模プロジェクトにはあまり向いていない機能といえるかもしれません。

あと一時的にとはいえメモリ上に古いアセットバンドルと新しいアセットバンドルが同時に乗ることになるのでその点もどうなんだろうという所感です。

参考

docs.unity3d.com