aab環境で150M超えそうな場合の対処unity2021.3.17版
結論
アプリ分割と容量ダイエットを検討します。
アプリ分割設定(Split Application Binary)をすることで、150M制約を突破できます。
この設定でしのぎつつ、storeの2G制約に触れないようアセットのダイエットを行っていきます。
調査/検証環境
unity 2021.3.17
アプリ分割
AndroidのPlayer設定から発行設定のSplit Application Binaryを有効にします。
scriptから行う場合、PlayerSettings.Android.useAPKExpansionFiles
をtrueに設定します。
Split Application Binary
有効にすると、unity内部でgoogleのPlay Asset Delivery(PAD)を使用して、
アプリケーションをベースモジュールとアセットパックに分割したAndroid App Bundle(AAB)を生成してくれます。
基本モジュール: 最初のシーンの実行可能ファイル (Java およびネイティブ)、プラグイン、およびアセットが含まれています。最初のシーンは、ビルド インデックスが0 のシーンです。
アセット パック: 残りのシーン、リソース、ストリーミング アセットなど、その他すべてが含まれています。ビルド時に Unity が生成するアセット パックの詳細については、生成されたアセット パック を参照してください。
分割することで、アセットパックの容量を含めて150Mを超えるバイナリの申請が可能になります。
起動シーンから直参照されているリソースはアセットパックに反映されないため注意が必要です。
PADの制限
AABの150M制約は突破できますが、PADによる容量制限を考慮する必要があります。
アセットパックはサイズの上限が大きいため、大規模なゲームに適しています。
fast-follow と on-demand の各アセットパックのダウンロード サイズの上限は 512 MB です。
すべての install-time アセットパックの合計ダウンロード サイズの上限は 1 GB です。
Android App Bundle に含まれるすべてのアセットパックの合計ダウンロード サイズの上限は 2 GB です。
Android App Bundle では、最大 50 個のアセットパックを使用できます。
install-time
はアプリのインストールと同時に配布され、アプリの起動と同時に使用可能なアセットです。
fast-follow
とon-demand
はダウンロードされるタイミングが違いますがアプリ起動時には存在しない可能性があるのでPADのAPIによって制御する必要があります。
Unity上の注意点
Unityでは後述する独自で分割したアセットパックを含め、分割されたアセットパックの合計が1G未満の場合1つのinstall-time
アセットパックとしてまとめてくれます。
1Gを超えた場合、StreamingAssetとその他でアセットパックを分割し、大きい物にinstall-time
それ以外をfast-follow
を割り当てます。
この際、部分的にfast-follow
が割り当てられたアセットの制御を開発者側が行う必要があるのかどうか、ドキュメントには見当たらなかったため検証が必要な可能性があります。
デメリット
テスト用アプリの配布システムが対応していない可能性があります。 [1]
検証環境ではバイナリのダウンロードは出来ても起動に失敗するといった挙動が発生しました。
それ自体は開発環境と本番環境で設定を分けることで回避できますが、
アセットパックがinstall-time
以外の設定の場合、本番と開発環境に挙動差分が発生するので注意が必要です。
容量ダイエット
アセットパックとの分割を行ったAABでも2Gの制限があります。
ここに抵触しないように容量の減らしていく方法を検討します。
1.圧縮度を上げる
アセットの圧縮度を上げるのは品質や読み込み負荷とのトレードオフにななります。
プロダクトに合わせて計測しながら最適解を探していく必要があります。
テクスチャ
フォーマット
対象OpenGLのバージョン次第ではありますが、ASTC or ETC2になるかと思います。
ETC系は知見がないので言及しませんが、ASTCであれば品質とのバランス的に透過ありを6×6、不透明を8×8が上限になるよう調整するのが良さそうです。[2]
ASTCの圧縮度に対して発生するアーティファクトについてはこちらの記事が参考になります。
MaxSize
圧縮度とは関係ありませんが、texture設定のmaxSize
を下げる事でも容量を下げることが可能です。
元のテクスチャサイズより低い設定にすると、ゲーム内の解像度が下がるのでリソース毎に調整が必要です。
詳しくはこちらに記載があります。
Mip Maps
設定を切ることで33%ほど容量を削減できます。
UIで使用するテクスチャ、スカイボックスや最初から小さなテクスチャなどmipMapが不要なテクスチャは切って置くと良さそうです。
メッシュ
Vertex Compression と Mesh Compression
精度を低くする又はRunitme時に解凍することで容量を減らす事ができます。
モデルによってどこまで許容できるか変わるためリソース毎の調整が必要です。
サウンド
Compression Format
Compression Formatは3つあり、それぞれ下記効果が期待できます。
PCM : 非圧縮なので容量が大きいが再生レイテンシは低い。長いとメモリプレッシャーが高くなる。
ADPCM : 圧縮可能、再生負荷もそこまで高くないがが苦手な音源がある。
Vorbis : 圧縮率を幅広く調整できるが、再生負荷が高い。
再生品質と調整する前提ですが、容量的にはVorbisにして圧縮をかけるのが効果的です。
要件的に難しい物のみPCMやADPCMを検討します。
こちらに圧縮倍率や起こる音源の変化など詳しくまとまっていて参考になります。
再生品質に圧縮設定以外のオーディオクリップ設定も大きく影響するので、再生方法も含めて調整が必要です。[3]
少し古いですが、Unity 2017最適化ガイドの4章に詳しくまとまっているので参考になります。
2.アセットバンドルの導入
アセットバンドルとはunityに実装されているアセットをアーカイブファイル化して取り扱う機能です。
アプリケーションからアセットを切り離してアプリサイズを抑えたり、
アーカイブに暗号化をかけることでビルドインリソースのセキュリティ向上が行えます。
アセットバンドルのAPIを直に扱うか、公式がラップしているAdressableAssetSystemを使用することで導入が可能です。
アセットバンドル/AdressableAssetSystemはかなり複雑で、
詳細を説明すると記事の趣旨から外れてしまうため配布方法のイメージ程度に留めます。
詳しく知りたい方はこちらを参照してください。
アセバンを自前インフラに逃す
下記のような構成が必要になります。
ビルドしたアセットバンドルを自前で管理しているインフラに置いて提供します。
青色の部分は開発者側で開発/管理する必要がありコストがかかります。[4]
メリットとしては、アセバンの提供に関してosに依存することがないため、
iosでも同じ仕組みでアセットバンドルを提供することができます。
アセバンをpadでGoogle Play Storeに逃す
下記のような構成になります。
ビルドされたアセットバンドルは、先述した通りアセットパックとしてabbバイナリに内包されます。
max 2Gという容量制限こそありますがダウンロードの仕方も含め、Google Play Storeの機能を利用するため開発コストや管理コストを自前に比べ抑える事ができます。
デメリットとしてはGoogle Play Storeの機能を利用するためiosでは使えず、別の方法を取らないといけない点が挙げられます。
まとめ
abb環境で150M超えそうな場合は、
1.Split Application Binaryでアプリ分割
2.圧縮等を考慮しつつなるべくアセットバンドルでcdnやstoreに逃がす。
こちらの対処していきましょう。
注釈
-
emlauncherを使わせて頂いたのですが、install-timeのアセットを内包したところ起動しませんでした。 ↩︎
-
あくまでエンジニア目線なので、最終的な調整はデザイナさんとの調整が必要です。 ↩︎
-
Load Typeを何にするか、Load In Background/Preload Audio Dataを有効にするかなど。 ↩︎
-
Cloud Content DeliveryやjenkinsなどのSaasの構成にもよります ↩︎
Discussion