Unreal Engine のコアゲーム ロジックは C++ または Blueprints で記述されていますが、Android パッケージングでは、Java と Kotlin のバイトコード(classes.dex)をコンパイルして、GameActivity ライフサイクル イベント、Google Play 開発者サービス、課金、オーディオ、アナリティクスのプラグインを処理します。
Android Gradle プラグイン(AGP)のデフォルトのコード圧縮ツールおよびオプティマイザーである R8 は、未使用のクラスとメソッドを削除し、バイトコードを最適化します。これにより、パッケージのダウンロード サイズが小さくなるだけでなく、メモリマップド(mmap)DEX ページのランタイム メモリ使用量とベースライン Java プロセスのオーバーヘッドも削減され、物理メモリの負荷とローメモリ キラー(LMK)による終了が軽減されます。Google Play は、Android Vitals の DEX コードの最適化指標を通じて、ゲームの DEX 最適化レベルもモニタリングします。
デフォルトの動作と Unreal Engine バージョンのサポート
UE 4.22.0 以降、Unreal Engine の UEDeployAndroid.cs は、生成された Android リリースビルド構成(buildAdditions.gradle)にデフォルトで minifyEnabled true を挿入します。UE 4.25 では、バンドルされているツールチェーンが AGP 4.0.0 にアップグレードされたため、UE 4.25 以降のすべてのリリース(出荷および配布)ビルドで、追加の設定なしで R8 がデフォルトで有効(true)になります。
| Unreal Engine のバージョン | バンドルされた AGP | リリース デフォルト | デバッグのデフォルト | 動作 |
|---|---|---|---|---|
| UE 4.21 以前 | 以前の Gradle または Ant | 無効(false) |
無効(false) |
エンジンによって挿入された minifyEnabled 構成はありません。 |
| UE 4.22 ~ 4.24 | 3.4 より前 | 有効(ProGuard) | 無効(false) |
minifyEnabled true は、リリースビルドでデフォルトで有効になっています(ProGuard を実行します)。 |
| UE 4.25 ~ 5.3 | 4.0.0 | 有効(R8) | 無効(false) |
AGP 4.0 を採用すると、リリースビルドで R8 がデフォルトで実行されます。 |
| UE 5.4 ~ 5.7 | 7.4.2 | 有効(R8) | 無効(false) |
AGP 7.x では、以前の useProguard オプションが削除され、R8 が排他的に実行されます。 |
| UE 5.8(5.8.3 以降) | 8.13.0 | 有効(R8) | 無効(false) |
デフォルトで AGP 8.x と最新の R8 最適化パイプラインを使用します。 |
リリースビルドとデバッグビルドの違い
UnrealBuildTool(UEDeployAndroid.cs)は、生成された buildAdditions.gradle ファイルをリリースビルドとデバッグビルドで異なる方法で構成します。
buildTypes {
release {
signingConfig signingConfigs.release
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
debug {
debuggable true
signingConfig signingConfigs.debug
}
}
- リリース(出荷または配布):
minifyEnabled trueを設定し、デフォルトでproguard-rules.proを適用して、R8 コードの圧縮と難読化を実行します。 - デバッグ(開発):
debuggable trueを有効にし、minifyEnabledを省略(デフォルトはfalse)して、高速なビルド イテレーションとシンボル デバッグを維持します。
Unreal Plugin Language(UPL)を使用して保持ルールを追加する
R8 は UE 4.25 以降のリリースビルドで自動的に実行されるため、C++ JNI(JNIEnv->FindClass、GetMethodID)またはマニフェストを介してのみアクセスされる Java クラスを保持する必要があります。Java 呼び出しサイトのないクラスは未使用として扱われ、R8 によって削除されます。これにより、開発ビルドで動作する機能が、リリースビルドで ClassNotFoundException または NoSuchMethodError で失敗する可能性があります。
Unreal Plugin Language(UPL)の XML ファイルで <proguardAdditions> タグを使用して、パッケージ化中にカスタムの keep ルールを proguard-rules.pro にマージします。プロジェクトまたはプラグインの *_UPL.xml ファイルに次のブロックを追加します。
<root xmlns:android="http://schemas.android.com/apk/res/android">
<proguardAdditions>
<insert>
-keep class com.epicgames.unreal.** { *; }
-keep class com.example.plugin.** { public *; }
-dontwarn com.example.plugin.**
</insert>
</proguardAdditions>
</root>
一般的な問題のトラブルシューティング
このセクションでは、Unreal Engine で R8 を使用する際の一般的なパッケージ化とランタイムの問題を解決する方法について説明します。
デバッグ用に R8 を一時的に無効にする
リリース専用のクラッシュが、R8 が必要なクラスを削除したことが原因かどうかを特定するには、UPL ファイルの <gradleProperties> の下に DISABLE_MINIFY=1 を挿入します。UEDeployAndroid.cs が存在する場合、minifyEnabled false が生成されます。
<gradleProperties>
<insert>
DISABLE_MINIFY=1
</insert>
</gradleProperties>
Missing classes detected while running R8 件のパッケージ化エラー
UE 5.4 以降(AGP 7.4.2+)では、R8 は厳格なクラス欠落チェックを適用します。このエラーでパッケージ化が失敗した場合は、中間ビルド ディレクトリ(Intermediate/Android/.../gradle/app/build/outputs/mapping/release/missing_rules.txt の下)の missing_rules.txt を調べて、欠落しているライブラリ依存関係または必要なルールを UPL ファイルの <proguardAdditions> に追加します。
R8 フルモードとサードパーティ SDK の互換性
UE 5.8 以降(AGP 8.13.0+)では、より積極的な最適化を行うために、R8 フルモードがデフォルトで有効になっています。リフレクションの問題が原因で、以前のサードパーティ製 Android SDK が実行時に失敗する場合は、プラグインの ProGuard ルールを更新するか、UPL ファイルに次のプロパティを追加して R8 を互換モードに戻します。
<gradleProperties>
<insert>
android.enableR8.fullMode=false
</insert>
</gradleProperties>