unagirabbit's blog

気づいたことをメモしています

UnityでAndroid App Bundleが150MBを超えた時の対応

2021年8月より、Google Playでの新規アプリの公開はAndroid App Bundleで行う必要があります。
新規アプリのサイズが 150 MB を超える場合は、
Play Asset Delivery または Play Feature Delivery のいずれかを使用する必要があります。

developer.android.com

apkならobbで楽に行えるのですがaabはobbが使えないのでそう簡単にはいきません。
未対応で150MB超えていると、PlayConsoleアップ時に以下のエラーとなります。

App Bundle に含まれている設定(ARM64_V8A)で、初期インストールのサイズは 150 MB 以下である必要があります。

developer.android.com

Play Asset Deliveryを利用することで、アプリ内包(BuiltIn)しているAssetBundleをAsset Packとして扱うようにします。
そのAssetBundleはサイズから除外してくれるので150MBを超えててもOKになります。
StreamingAssetsにおいてたものをAssetPackに移動させるイメージです。
このために実装を切り分けないといけないのは辛い所です。

非対応な構成

公式だと現時点ではAddressablesは非対応です。
対応されている方もいらっしゃるので以下参考にどうぞ。
Android App Bundle with Addressable #14

また、Gradleプロジェクトを出力してのビルドも非対応です。
Build app bundle in android studio with asset packs of Unity project #31
その場合はJavaネイティブアプリとして対応すれば可能なのか?
https://developer.android.com/guide/app-bundle/asset-delivery/build-native-java?hl=ja

環境

Unity: 2019.4.21f1
Android: Pixel 4a(11)

Google Play Asset Delivery: 1.3.0
Google Play Common: 1.3.0
Google Play Core: 1.3.0
Google Android App Bundle: 1.3.0

対応

公式ドキュメントはこちらです。
読み進めれば問題なく対応できました。
https://developer.android.com/guide/app-bundle/asset-delivery?hl=ja

プラグインをインストールする

unitypackageでインポートすることもできますが、管理しやすいUPMでインストールします。
Packages/manifest.jsonGoogleレジストリを追加します。

"scopedRegistries": [
    {
      "name": "Game Package Registry by Google",
      "url": "https://unityregistry-pa.googleapis.com",
      "scopes": [
        "com.google"
      ]
    }
  ]

Unityが2018の方は利用できないので以下からpackageを入手しましょう。
https://github.com/google/play-unity-plugins

必要なパッケージは以下です。
Google Play Asset Delivery
Google Play Common
Google Play Core
Google Android App Bundle

AssetBundleをAssetPackに含めるよう設定する

UIでの設定もできますが使いづらいのでスクリプトで行います。
UIからだとAssetBundleManifestがないとエラーになります。
依存が関係ないようなAssetBundleであればスクリプトで設定しましょう。
異なるAssetPackに同じファイルが存在するとビルドエラーになります。

今回はBuiltInなアセットなのでDelivery ModeはすべてInstall Timeにします。

using Google.Android.AppBundle.Editor;
using Google.Android.AppBundle.Editor.AssetPacks;

private static void AssetDeliverySettings()
{
    var assetPackConfig = new AssetPackConfig();
    // AssetBundle以外のものをAssetPackに含めたい場合はこちら
    // ひとつのAssetPackに指定フォルダ以下にあるファイル全てを含めます
    assetPackConfig.AddAssetsFolder("{AssetPack名}", "{対象フォルダ相対パス}", AssetPackDeliveryMode.InstallTime);

    // AssetBundleを個別に追加する場合はこちら
    // AssetPack名=AssetBundle名になる
    assetPackConfig.AddAssetBundle("{AssetBundle相対パス}", AssetPackDeliveryMode.InstallTime);

    // 設定を保存
    AssetPackConfigSerializer.SaveConfig(assetPackConfig);
}

設定ファイルはLibrary/PlayAssetPackConfig.jsonに保存されます。

AssetPackからロードするように実装する

AssetPackとAssetBundleを指定してAssetBundleを取得し、Assetをロードします。
AssetPack名を設定した場合はpackとbundleの両方名が必要です。

// AssetPack名とAssetBundle名が同じ場合はAssetPack指定を省略できる
private void LoadAsset1(string assetBundleName, string fileName)
{
  var bundleRequest = PlayAssetDelivery.RetrieveAssetBundleAsync(assetBundleName);
  bundleRequest.Completed += request => {
      if(request.Status == AssetDeliveryStatus.Loaded ||
      request.Status == AssetDeliveryStatus.Available) {
          var prefab = request.AssetBundle.LoadAsset<GameObject>(fileName);
          Instantiate(prefab);
      }
  };
}
// 異なる場合は別途指定
private void LoadAsset2(string assetPackName, string assetBundlePath, string fileName)
{
  var packRequest = PlayAssetDelivery.RetrieveAssetPackAsync(assetPackName);
  packRequest.Completed += request => {
      if(request.Status == AssetDeliveryStatus.Loaded ||
      request.Status == AssetDeliveryStatus.Available) {
          var bundleCreateRequest = packRequest.LoadAssetBundleAsync(assetBundlePath);
          bundleCreateRequest.completed += _ => {
              var prefab = bundleCreateRequest.assetBundle.LoadAsset<GameObject>(fileName);
              Instantiate(prefab);
          };
      };
  };
}

Android App Bundleをビルドする

設定をロードしてaabをビルドします。
Unityのメニューから[Google]->[Build Android App Bundle...]でビルドできます。
aabが150MBを超える場合は警告が表示されます。
[PlayerSettings]->[Warm about App Bundle size]で非表示にできます。

スクリプトで行う場合はこちら。

private static void BuildAndroidAppBundle()
{
    var assetPackConfig = AssetPackConfigSerializer.LoadConfig();
    // 良しなに設定する
    var options = new BuildPlayerOptions(){
        locationPathName = "application.aab",
        target = BuildTarget.Android,
        targetGroup = BuildTargetGroup.Android
    };
    Bundletool.BuildBundle(options, assetPackConfig);
}

動作確認する

端末を繋いでいれば、Unityのメニューから[Google]->[Build and Run]でaabのビルドとAssetPackのインストールが行えます。
ビルドしたaabをコマンドラインからインストールするにはこちらからどうぞ。
developer.android.com

参考ページ

deep-verdure.hatenablog.com

github.com

github.com