えんじにあ・めも

日々の生活に役立つ記事をエンジニア視点で

UnityでGoogle Play Storeの64ビット要件対応の対応をする

この前UnityのアプリをGoogle Play Storeのアルファチャンネルにアップロードした時、64ビット対応の警告が出ていました。
そういえば、1月頃にこんなアナウンスがありました。

android-developers.googleblog.com

2017年頃からアナウンスはされてたんですが、2019年8月1日からGoogle Play Storeにアップロードする全てのネイティブコードを含むアプリに対して64ビットバイナリを含める事が必須となります。
例外としてゲームデベロッパー向けにUnity 5.6系に関しては2021年8月までは更新を受け入れてくれるようです。

つまりどういうことだってばよ?

Unity 2017以降を使用しているゲームデベロッパーはArm64バイナリのビルドが必須になります。
もうちょっと正確にいうと、AndroidもMonoではなくIL2CPPかつARM64(Target Architectureチェックいれて)
ビルドしなければいけません。
Storeの64ビット対応のためにIL2CPPを使うのがちょっと混乱してて記事も少ないのですが、 ココらへんの歴史的背景はiOSと同じでMonoのランタイムは32Bitにしか対応していないので使えないのです。

UnityでAndroidのArm64対応APKを出力するには

まずUnityのバージョンですが5.6系は無理なので気合でバージョンアップするか諦めます(ええ・・・)
Unity 2017に関してはArm64ビルドのバックポートがLTS版のUnity 2017.4.16f1から入っているのでLTS版まで更新します。
Unity 2018以降はUnity 2018.2からARM64ビルドがサポートされてます。

blogs.unity3d.com

次にPlayer Settingsを開いてScripting BackendをIL2CPP、Target ArchitectureのARM64にチェックを入れます。
これで準備完了!あとはビルドするだけ

しかしそう簡単にビルドは通らない

新規プロジェクトならともかく、プロダクトの終盤でこの問題に気づいて
この設定を入れたらまず100%ビルドは通りません。
やっとビルド出来たと思ったら起動直後に落ちます。
今まで見たことのない訳のわからないエラーでエンジニアは七転八倒します。
しかし落ち着いて対応しましょう。
まずは初歩的な事として、Android NDKがちゃんと設定されているか確認します。
入ってない場合は、こちらの記事

kurokuru.hatenablog.com

次に、IL2CPPのビルドで出るエラーは(大抵)ネイティブライブラリの64ビット版が入ってないからです。
ネイティブライブラリとは、つまるところPlugins/Androidとかに入っている.soライブラリのことです。
代表的なライブラリとしては

  • Firebase Unity SDK
    こちらはFirebase SDK 5.2.0からARM64をサポートしていますので古い場合は最新版に更新しましょう。
    そのときは一旦Firebaseを全て消したほうがゴミが残らないので安心です。

  • Play Games Plugin for Unity
    0.9.51からARM64対応です。こちらも最新版になってるかチェックしましょう。

Firebaseなどを入れた時に付属しているPlayServicesResolverの自動Resolverを切っている場合は手動で動かして更新を掛けます。
他にもビルドが失敗している、起動したら落ちる場合logcatを見て読み込めないライブラリを特定し
そのライブラリの更新をチェックします。
よっぽど特殊なライブラリでなければ、ARM64対応していないということは無いと思います。
ただし、自分で用意した.soなどはARM64でリビルドする必要があります。
この時、ARM64版はAssets/Plugins/Android/libs/arm64-v8aに入れましょう。

IL2CPP自体はエイリアンテクノロジーで大分こなれているのでそれ起因の不具合は少ないと思います。
特にiOS同時開発の場合はiOS側のほうが(主にApple側の制約で)不具合を引くことがあるので
一度動けばスムーズに動くはずです。
処理速度の方はあんまり早くなったように思えないけど・・・。

注意点としてIL2CPPにした場合、iOSと同じようにビルド時間が長くなります。
特にCppCompilerConfigurationをRelease/Masterにすると半端なく長いです。
動作確認で手元でビルドするときはDebugにするか、IL2CPP出力はバッチビルド時だけにしてMonoで出力するほうが良いでしょう。
iOSと違ってランタイム制約がないので、Monoはそのまま使うことが出来ます。