AR機能を実装した時に発生した問題について
「Light Box」をリリースした時に、AR周りで幾つか問題が発生したので記録しておく。
リリースビルドを実行した時に進行不能になる
症状
デバッグ時は問題無かったが、リリース用ビルドで実機動作中、タイトル画面→ARモードでステージ選択後、画面が固まってしまい、進行不能となる。
↑すっげぇ白くなってる、はっきりわかんだね(実機画面)
発生タイミングとしては、ARパーミッションをデバイスに要求→『写真と動画の撮影を「LightBox」に許可しますか?』と表示→「アプリの使用時のみ」を選択→画面がフェードから戻らず進行不能、といった感じ。
Development Buildにチェックを入れ、Logcatで確認。
Error Unity AndroidJavaException: java.lang.ClassNotFoundException: com.unity3d.plugin.UnityAndroidPermissions
Error Unity java.lang.ClassNotFoundException: com.unity3d.plugin.UnityAndroidPermissions
Error Unity at java.lang.Class.classForName(Native Method)
Error Unity at java.lang.Class.forName(Class.java:454)
Error Unity at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
Error Unity at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)
Error Unity at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95)
Error Unity at android.os.Handler.dispatchMessage(Handler.java:102)
Error Unity at android.os.Looper.loop(Looper.java:223)
Error Unity at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
Error Unity Caused by: java.lang.ClassNotFoundException: Didn't find class "com.unity3d.plugin.UnityAndroidPermissions" on path: DexPathList[[zip file "/data/app/~~6OQboNqpCcR6KgGodnVAtA==/com.TukikusaGames.LightBox-e1MqvBlCm-By3zu50bmN1g==/base.apk"],nativeLibraryDirectories=[/data/app/~~6OQboNqpCcR6KgGodnVAtA==/com.TukikusaGames.LightBox-e1MqvBlCm-By3zu50bmN1g==/lib/arm, /data/app/~~6OQboNqpCcR6KgGodnV
ファッ!?
注目すべきは1行目、
java.lang.ClassNotFoundException: com.unity3d.plugin.UnityAndroidPermissions
要するに「com.unity3d.plugin.UnityAndroidPermissionsクラスが見つからないよ」って言ってる。
原因
結論からいうと、これ。
Unity Android ビルドの Minify オプションの罠 - もんりぃ is undefined.
Minifyっていうのは、コードの最適化・難読化を行ってくれる機構らしい。
公式ドキュメント(英文、Google翻訳使用)によると、
Minifyは、アプリケーションのコードを縮小、難読化、最適化するプロセスです。コードサイズを縮小し、コードを分解しにくくすることができます。
Minify設定を使用して、UnityがビルドにMinifyを適用するタイミングと方法を定義します。 ほとんどの場合、ビルドのデバッグではなく、リリースビルドにのみMinifyを適用することをお勧めします。これは、縮小に時間がかかり、ビルドが遅くなる可能性があるためです。また、コードが最適化されるため、デバッグがより複雑になる可能性があります。
調査してみたところ、リリースビルド時にはMinifyを使用する必要があるのだが、難読化を行う際にクラス名が行方不明となってしまう場合がある。そのため、エラーの発生したクラス名を難読化が行われないように回避する必要がある。
今回は、com.unity3d.plugin.UnityAndroidPermissionsクラスがそう。
対策
Minify設定のすぐ上、「Custom Proguard File」にチェックを入れる。すると、Assets\Plugins\Android\Proguard-user.txt が自動的に作成される。
ファイルは↑こ↓こ
そして、作成されたファイルを開き、編集する。中身はシンプルな .txtファイルなので、メモ帳か何かで開けば良い。
-keep class com.unity3d.plugin.** {
*;
}
「com.unity3d.plugin.**」とすることで、~plugin以下のクラスがすべて難読化回避される。
あとは再ビルドして、動作を確認。問題なし。
対応端末が著しく減る
症状
何気なくビルドしたAppBundleを、Google Play Consoleからアップロードしたところ、
なんか少ない…少なくない?
というのも、2022年3月現在、Google Play Consoleのデバイスカタログでは21,252種類とかなりのデバイスが登録されているのだが、仮にAndroid7.0以上(AR CoreはAPIレベル24以上必須 https://developers.google.com/ar/devices)としても、流石に1000以下は無いと思うんだよなぁ…
原因
と思って、「機能」を見てみる。
ここに、アプリで要求される必須機能一覧(マニフェスト)が表示されており、この内容によって対応するデバイスにフィルターが掛かっているのだが、
ん?何だぁ、これは~?(ねっとり)
対策
UnityのProject Settingsから、ARCore→Depth APIを「Require(必須)」から「Optional(オプション)」に切り替えるだけ。
Depth adds realism | ARCore | Google Developers
ARのDepth機能は、要するに画面上のARで表示されたモノが、椅子とか机とか現実のモノに隠れて、よりリアルに見えるための機能だ。(詳しくは上記リンク参照)
「LightBox」でも何気に使用している機能だが、別に無くてもARは動作はするので、必須というわけではない。
設定を切り替えて再アップロードしてみる。
「機能」から「com.google.ar.core.depth」表示が消え、対応デバイスも倍くらいになった。めでたしめでたし。