CORETECH ENGINEER BLOG

株式会社サイバーエージェント SGEコア技術本部 技術ブログ

【Addressables】Addressablesをもっと便利にする②

こんにちは、SGEコア技術本部(コアテク)基盤チーム所属の袴田です。

基盤チームでは各子会社で利用される基盤開発をメイン業務としています。 開発した基盤のいくつかはOSSとして公開もしています。

github.com

前回から半年以上間が空いてしまいましたが、引き続きAddressablesに施した改修について紹介していきます。今回はカタログのファイルサイズやメモリ使用量に関わる改善です。

本記事の改修に関わる機能

Addressablesでは管理するアセットを参照できる型として AssetReference があります。

MonoBehaviourScriptableObject のフィールドとしてこのクラスを追加すると、インスペクタから参照するアセットを指定できます。サブクラスやジェネリックサブクラスも提供されていて、選択できるアセットの型を制限することもできます。内部的にはアセットのGUIDをシリアライズして保持しています。

詳細については公式マニュアルも参照してみてください。

docs.unity3d.com

アセットのGUIDは初期設定から変えていない場合、アドレスと同様にカタログに記載されて、アセットをロードする際のキーとして利用できます。

これを切り替える設定項目はグループの Include GUIDs in Catalog です。インスペクタ上のツールチップでは「GUIDが不要な場合は無効にするとカタログサイズを削減するのに役立つ」と案内されていますが、そのGUIDを必要とする機能のひとつが AssetReference ということです。
Addressablesのソースコードを閲覧すると、IncludeGUIDInCatalog プロパティのドキュメントコメントには If enabled, guids are included in content catalogs. This is required if assets are to be loaded via AssetReference. と記載されているので間違いないでしょう。

カタログサイズを削減できると下記のようなメリットがあります。

  • ダウンロード時間の短縮
  • 読み込み時間の短縮
  • 使用メモリの削減

AssetReference はインスペクタ上で設定できるため非エンジニアでも扱いやすく便利ですが、これらのメリットを得ようとすると使用できなくなってしまいます。AssetReference を使用しているアセットだけ別グループに切り分けるというのも手段のひとつではありますが、漏れが無いように検知して振り分けるツールが別途必要になったり、使用するアセットがあまりにも多いと削減効果が得られなかったりと悩ましいです。

改修内容

GUIDではなくアドレスで記憶する AssetAddressReference およびそのサブクラス群を追加しました。

一見するとシンプルな改修ですが、いくつか気をつけなければならない点があります。

AssetReference には設定されているアセットがAddressablesに登録されているかを調べて、未登録であれば登録をサジェストする機能があります。しかし AddressableAssetSettings は登録されているアセットをGUIDベースで管理しているため、アドレスだけではこの照合が難しくなります。
またアセットが登録されたままアドレスだけ変更になった場合、新しいアドレスへの更新を促せるとユーザビリティの向上にも繋がります。

これらの課題を解決するため、AssetAddressReference は基本的には従来の AssetReference をベースに、アドレス+Unityエディタ用のGUIDという構成にすることで、アセットの照合やアドレス変更の検知を可能にしています。

GUIDを保持するフィールドを #if UNITY_EDITOR ディレクティブで括ることでビルド時にはGUIDに関しては取り除かれるので、実機向けビルドではアドレスのみがシリアライズされた状態になります。

[Serializable]
public class AssetAddressReference : IKeyEvaluator
{
    [SerializeField]
    protected internal string m_Address = "";

#if UNITY_EDITOR
    [SerializeField]
    protected internal string m_AssetGUID = "";
#endif
    // ... 以下略
}

*アセットのバリデーションや変更検知などを行う AssetReferenceDrawerUtilities にも対応が必要です。

総括

改修としてはわりと低コストながら、カタログサイズの削減というメリットが見込める改修となっています。特に大量のアセットを扱う大規模プロジェクトでその効果(10万アセットあった場合、3MB以上削減)が期待できます。

AssetReference および AssetReferenceDrawerUtilities を改修して全てアドレスで記録される方式に統一するアプローチと、別クラスとして AssetAddressReference および AssetAddressReferenceDrawerUtilities を実装して使い分けられるようにするアプローチがあります。 基盤チームの方針として『利用者の選択肢はなるべく広く』というのがあるので、今回は後者の方式で実装しています。

今回は AssetReference の課題を解決し、カタログサイズの削減とエディタでの使いやすさを両立する AssetAddressReference について紹介しました。

大規模なプロジェクトではカタログサイズの削減効果は大きく、ダウンロード時間の短縮やメモリ使用量の削減に寄与します。一方で、従来の機能や使い勝手を維持できているため、移行しやすい改修となっています。

次回も引き続きAddressablesの便利な改修について紹介予定ですので、お楽しみに!