Riduci e ottimizza il codice Unity con R8

Sebbene la logica di gioco di base in Unity sia scritta in C# (compilata con IL2CPP), le build Android includono un bytecode Java e Kotlin sostanziale (classes.dex) per gestire gli eventi del ciclo di vita di UnityPlayerActivity, Google Play Services, fatturazione, annunci e SDK social.

L'attivazione di R8, lo strumento di compressione e ottimizzazione del codice predefinito nel plug-in Android Gradle (AGP), rimuove le classi e i metodi inutilizzati e ottimizza il bytecode. In questo modo, non solo riduci le dimensioni di download dell'app, ma anche il footprint della memoria di runtime delle pagine DEX mappate in memoria (mmap) e l'overhead del processo Java di base, riducendo la pressione sulla memoria fisica e le terminazioni 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 Unity

In Unity, la minimizzazione del codice è disattivata per impostazione predefinita (false) per le build Release e build di debug quando crei un nuovo progetto.

Unity ha introdotto per la prima volta R8 come opzione di attivazione/disattivazione in Unity 2020.1.0f1. A partire da Unity 2022.2.0f1 (e con backporting a Unity 2021.3.41f1 LTS), Unity ha eseguito l'upgrade della toolchain in bundle ad AGP 7.1.2 e versioni successive, ha rimosso il supporto di ProGuard legacy ed esegue R8 esclusivamente ogni volta che la minimizzazione è abilitata.

Versione Unity AGP in bundle Release predefinita Supporto di R8 e configurazione richiesta
2019.4 LTS e versioni precedenti Precedente alla versione 3.4 Disattivata (false) Non supportato (solo ProGuard legacy).
Da 2020.1.0f1 a 2021.3.40f1 Da 3,4 a 4,0 Disattivata (false) Facoltativo (il valore predefinito è ProGuard). Attiva sia Minify > Release (Minimizza > Release) sia Use R8 (Usa R8).
2021.3.41f1 e versioni successive (2021 LTS) 7.1+ Disattivata (false) Solo R8. Attiva Minify > Release (Minimizza > Release) per eseguire automaticamente R8.
Da 2022.2.0f1 a Unity 6 e versioni successive 7.1 a 8.x Disattivata (false) Solo R8. Attiva Minify > Release (Minimizza > Release) per eseguire automaticamente R8.

Attiva R8 in Player Settings (Impostazioni player)

Per attivare la compressione e l'ottimizzazione del codice R8 per le build di release:

  1. Nell'editor di Unity, apri Edit > Project Settings e seleziona Player.
  2. Seleziona la scheda Android ed espandi Publishing Settings > Build.
  3. Nella sezione Minify (Minimizza), configura le opzioni per la tua versione di Unity:
    • Unity 2021.3.41f1 e versioni successive e 2022.2.0f1 e versioni successive: seleziona Release (Release). Unity esegue R8 automaticamente durante l'attività Gradle minifyReleaseWithR8.
    • Unity dalla versione 2020.1.0f1 alla versione 2021.3.40f1: seleziona sia Release sia Use R8.

Se automatizzi le build utilizzando gli script dell'editor C#, configura queste proprietà tramite PlayerSettings.Android:

using UnityEditor;

public static class AndroidBuildConfig
{
    public static void EnableR8ForRelease()
    {
        PlayerSettings.Android.minifyRelease = true;

        // Required only in Unity 2020.1.0f1 to 2021.3.40f1 and 2022.1 or earlier
        // (In Unity 2021.3.41f1+ and 2022.2+, R8 is always used when minification is enabled)
#if !UNITY_2022_2_OR_NEWER
        PlayerSettings.Android.minifyWithR8 = true;
#endif
    }
}

Aggiungi regole di conservazione per JNI e reflection

Le classi e i metodi Java richiamati dinamicamente dagli script C# utilizzando AndroidJavaClass o AndroidJavaObject non hanno siti di chiamata Java statici. Senza regole di conservazione esplicite, R8 potrebbe considerare queste classi inutilizzate e rimuoverle o rinominarle.

Per conservare i bridge Java personalizzati:

  1. In Impostazioni progetto > Player > Android > Publishing Settings > Build, attiva Custom Proguard File.
  2. Apri il file Assets/Plugins/Android/proguard-user.txt generato.
  3. Aggiungi regole -keep per le classi a cui si accede tramite JNI o richieste da plug-in di terze parti:
# Keep custom Java classes invoked from C# using JNI bridges
-keep class com.example.yourgame.** { *; }

# Keep callback interfaces passed between C# and Java
-keep interface com.example.yourgame.IPluginCallback { *; }

Risolvere i problemi comuni

Questa sezione descrive come risolvere i problemi comuni di build e runtime quando utilizzi R8 in Unity.

Missing classes detected while running R8 errori di build

Nelle versioni di Unity che utilizzano AGP 7.0 e versioni successive (2021.3.41f1+ e 2022.2+), R8 applica controlli rigorosi per le classi mancanti. Se una build non va a buon fine con questo errore, controlla il file missing_rules.txt generato nella directory di output della build (in Library/Bee/Android/Prj/.../build/outputs/mapping/release/missing_rules.txt o Temp/gradleOut/...) e aggiungi le dipendenze o le regole richieste a proguard-user.txt. Per saperne di più sulla scrittura di regole di conservazione, consulta Personalizza il codice da conservare.

Compatibilità della modalità completa di R8 con i plug-in di terze parti

In AGP 8.0 e versioni successive (Unity 6 e versioni successive), la modalità completa R8 è attiva per impostazione predefinita per eseguire ottimizzazioni più aggressive. Se un plug-in Android legacy non va a buon fine 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:

  1. In Publishing Settings > Build (Impostazioni di pubblicazione > Build), attiva Custom Gradle Properties Template (Modello di proprietà Gradle personalizzate).
  2. Apri Assets/Plugins/Android/gradleTemplate.properties e aggiungi la seguente proprietà:
android.enableR8.fullMode=false