Riduci e ottimizza il codice di Unreal Engine con R8

Sebbene la logica di gioco principale in Unreal Engine sia scritta in C++ o Blueprints, il pacchetto Android compila il bytecode Java e Kotlin (classes.dex) per gestire gli eventi del ciclo di vita di GameActivity, Google Play Services, la fatturazione, l'audio e i plug-in di analisi.

R8, lo strumento di compressione e ottimizzazione del codice predefinito nel plug-in Android per Gradle (AGP), rimuove le classi e i metodi inutilizzati e ottimizza il bytecode. In questo modo, non solo diminuiscono le dimensioni di download del pacchetto, ma si riduce anche il footprint della memoria di runtime delle pagine DEX mappate in memoria (mmap) e l'overhead del processo Java di base, mitigando la pressione sulla memoria fisica e le terminazioni da parte del killer di memoria insufficiente (LMK). Google Play monitora anche i livelli di ottimizzazione DEX del tuo gioco tramite la metrica Ottimizzazione del codice DEX in Android vitals.

Comportamento predefinito e supporto delle versioni di Unreal Engine

A partire da UE 4.22.0, UEDeployAndroid.cs di Unreal Engine inserisce minifyEnabled true nella configurazione di build di release Android generata (buildAdditions.gradle) per impostazione predefinita. Poiché UE 4.25 ha eseguito l'upgrade della toolchain in bundle ad AGP 4.0.0, R8 è abilitato per impostazione predefinita (true) su tutte le build di release (spedizione e distribuzione) in UE 4.25 e versioni successive senza configurazione aggiuntiva.

Versione di Unreal Engine AGP in bundle Release predefinita Debug predefinito Comportamento
UE 4.21 e versioni precedenti Gradle o Ant legacy Disattivata (false) Disattivata (false) Nessuna configurazione minifyEnabled inserita dal motore.
UE 4.22-4.24 Precedente alla versione 3.4 Attivato (ProGuard) Disattivata (false) minifyEnabled true abilitato per impostazione predefinita nelle build di release (esegue ProGuard).
UE da 4.25 a 5.3 4.0.0 Attivato (R8) Disattivata (false) L'adozione di AGP 4.0 esegue R8 per impostazione predefinita nelle build di release.
UE 5.4 - 5.7 7.4.2 Attivato (R8) Disattivata (false) AGP 7.x rimuove le opzioni useProguard legacy; R8 viene eseguito in modo esclusivo.
UE 5.8 (5.8.3+) 8.13.0 Attivato (R8) Disattivata (false) Utilizza AGP 8.x e le moderne pipeline di ottimizzazione R8 per impostazione predefinita.

Differenze tra build di release e di debug

UnrealBuildTool (UEDeployAndroid.cs) configura il file buildAdditions.gradle generato in modo diverso per le build di release e di debug:

buildTypes {
    release {
        signingConfig signingConfigs.release
        minifyEnabled true
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
    debug {
        debuggable true
        signingConfig signingConfigs.debug
    }
}
  • Release (spedizione o distribuzione): imposta minifyEnabled true e applica proguard-rules.pro per impostazione predefinita, eseguendo la riduzione del codice e l'offuscamento del codice R8.
  • Debug (Sviluppo): attiva debuggable true e omette minifyEnabled (il valore predefinito è false) per preservare l'iterazione rapida della build e il debug dei simboli.

Aggiungi regole di conservazione utilizzando Unreal Plugin Language (UPL)

Poiché R8 viene eseguito automaticamente sulle build di release in UE 4.25 e versioni successive, devi conservare le classi Java raggiunte solo tramite JNI C++ (JNIEnv->FindClass, GetMethodID) o il manifest. Le classi senza siti di chiamata Java vengono trattate come inutilizzate e rimosse da R8, il che può causare l'errore delle funzionalità che funzionano nelle build di sviluppo con ClassNotFoundException o NoSuchMethodError nelle build di spedizione.

Utilizza il tag <proguardAdditions> in un file XML Unreal Plugin Language (UPL) per unire le regole di conservazione personalizzate in proguard-rules.pro durante la pacchettizzazione. Aggiungi il seguente blocco al file *_UPL.xml del progetto o del plug-in:

<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>

Risolvere i problemi comuni

Questa sezione descrive come risolvere i problemi comuni di pacchettizzazione e runtime quando utilizzi R8 in Unreal Engine.

Disattiva temporaneamente R8 per il debug

Per isolare se un arresto anomalo solo per la release è causato dalla rimozione delle classi richieste da parte di R8, inserisci DISABLE_MINIFY=1 in <gradleProperties> nel file UPL. Se presente, UEDeployAndroid.cs genera minifyEnabled false:

<gradleProperties>
    <insert>
        DISABLE_MINIFY=1
    </insert>
</gradleProperties>

Missing classes detected while running R8 errori di pacchettizzazione

In UE 5.4 e versioni successive (AGP 7.4.2+), R8 applica controlli rigorosi per le classi mancanti. Se il packaging non va a buon fine con questo errore, controlla missing_rules.txt nella directory di build intermedia (in Intermediate/Android/.../gradle/app/build/outputs/mapping/release/missing_rules.txt) e aggiungi le dipendenze della libreria mancanti o le regole richieste a <proguardAdditions> nel file UPL.

Compatibilità della modalità completa di R8 con SDK di terze parti

In UE 5.8 e versioni successive (AGP 8.13.0+), la modalità completa R8 è abilitata per impostazione predefinita per eseguire ottimizzazioni più aggressive. Se un SDK Android di terze parti legacy non funziona in fase di runtime a causa di problemi di riflessione, aggiorna le regole ProGuard del plug-in o ripristina la modalità di compatibilità di R8 aggiungendo la seguente proprietà al file UPL:

<gradleProperties>
    <insert>
        android.enableR8.fullMode=false
    </insert>
</gradleProperties>