【Unity】AddressableAssetSystemメモ
前書き
まだよくわかってないので調べてみた内容をまとめておきます。
間違ってるところとかあるかも。
ScriptableObject 関連
AddressableAsset に組み込む際の要点
- ScriptableObject にアセット(Prefabなど)の参照を入れて AddressableAsset をビルドすると、
参照されているものも丸ごと bundle ファイルに入る
- ScriptableObject の中で ScriptableObject を参照した場合、
その ScriptableObject で参照されているアセットも bundle ファイルに入る
- ただし、その親 ScriptableObject 下で参照したアセットが被っていると、
さすがにアセットひとつのみのロードで済むっぽい - 本番環境 (Use Existing Build) とテスト環境 (Use AssetDatabase) で参照アセットが変わる
- 疑問点2参照
ScriptableObject に Prefab を配置すると bundle に含まれてしまう件
問題
- ScriptableObject をロードすればその下の Prefab も一緒にロードできる
…が、データベースを組むときに Prefab や Image まで含めてしまうと、
AddressableAsset のデータを小分けにロードできるメリットが失われる。
データベースなのにやたらサイズが大きくなるし、ロードが遅くなる。
解決方法
- AddressableGroup で別途アセットを配置したグループを作る。
これを AssetReference で参照すると Group(bundle)に含まずに済む。
ただしアセットを別途ロードしないと実体化できない。ちょっとめんどい。
疑問点1(→解決済)
- ScriptableObject の中で AssetReference を置いたとき、
スクリプトから参照してインスタンスすると null でエラーする??
- ロード処理(下記画像だと LoadWaitAsync)の while の条件式の問題だった。
while は ”条件式が真であるとき” ループし続ける仕組みなので、
PercentComplete < 1 だと 1 にならずに抜ける。<= だと永遠に回り続ける。
ので、確実にハンドルに参照が入ったかどうかをチェックする
handle.Result == null を使って、ロードが完全に終了したかどうかを見た。
- ロード処理(下記画像だと LoadWaitAsync)の while の条件式の問題だった。
疑問点2(→解決済)
- AddressableAsset の PlayModeScript の Use Existing Build を選択時、
ScriptableObject を直接グループに紐づけした状態で LoadAssetAsync した際、
該当する ScriptableObject は Project にある同名の ScriptableObject とは別扱いになるっぽい。 - つまり Project にある同名のアセットの値を変更しても反映されないということ。
ロードしたアセットは Project の同名アセットとは別扱いになる。 - Addressables経由 ScriptableObject 下にあるprivateメンバーの値が読めない。なぜ?
数値を変えたい private メンバーは [SerializeField] 属性をつけること!(ポカミス) - ちなみに AssetReference 経由の場合、オブジェクトの実体は editorAsset 経由で拾える。
handle.Result.assetReferenceGameObjects[0] では null を吐き出す。
正解は handle.Result.assetReferenceGameObjects[0].editorAsset。
ただし、editorAsset を使ってると アセットのビルド時にエラーを吐く。
上記の問題群に対する回答案
- PlayModeScriptの Use Asset Database ではアセットビルドを参照しない。
このモードでは Project上 の ScriptableObject 等アセットを参照する(確認済み)ので、
開発中は Use Asset Database で直接参照状態にしてデバッグ。
本番ではビルドして Use Existing Build で実行。 - 直接参照状態なら、Addressables からロードした別インスタンスにはならない。
エディタから ScriptableObject の値を変えてもランタイム終了時に保持される。
- 別インスタンス状態になると、本番環境ではランタイム終了時に消える
AssetReferenceTypeRestriction は廃止された
下記が詳しい。
ジェネリック型は通常のインスペクターで確認できない。
Odin でも AssetReference には対応してないのでどうしようもない。
補足1
ちなみに下記のようなものが模様。いろいろあるなあ。
LoadAssetAsync<T>(文字列) の文字列部分に下記の型の変数を配置すればOK。
- AssetReferenceAtlasedSprite
- AssetReferenceGameObject
- AssetReferenceSprite
- AssetReferenceT<>
- AssetReferenceTexture
- AssetReferenceTexture2D
- AssetReferenceTexture3D
補足2
AssetReference は Odin の [PreviewField] で画像ウィンドウが出せない。つらい。