Zmniejszanie i optymalizowanie kodu Unity za pomocą R8

Chociaż podstawowa logika gry w Unity jest napisana w języku C# (skompilowanym za pomocą IL2CPP), kompilacje na Androida zawierają znaczny kod bajtowy Javy i Kotlina (classes.dex) do obsługi zdarzeń cyklu życia UnityPlayerActivity, usług Google Play, płatności, reklam i pakietów SDK mediów społecznościowych.

Włączenie R8, domyślnego narzędzia do zmniejszania i optymalizacji kodu we wtyczce Androida do obsługi Gradle (AGP), usuwa nieużywane klasy i metody oraz optymalizuje kod bajtowy. Zmniejsza to nie tylko rozmiar pobieranej aplikacji, ale także wykorzystanie pamięci w czasie działania przez strony DEX mapowane w pamięci (mmap) i narzut podstawowego procesu Javy, co zmniejsza obciążenie pamięci fizycznej i ogranicza liczbę zakończeń przez low memory killer (LMK). Google Play monitoruje też poziomy optymalizacji plików DEX w grze za pomocą danych Optymalizacja kodu DEX w Android Vitals.

Działanie domyślne i obsługa wersji Unity

W Unity minifikacja kodu jest domyślnie wyłączona (false) zarówno w przypadku kompilacji wersji, jak i kompilacji do debugowania podczas tworzenia nowego projektu.

Unity po raz pierwszy wprowadziło R8 jako opcjonalny przełącznik w Unity 2020.1.0f1. Od wersji Unity 2022.2.0f1 (i w ramach portowania wstecznego do wersji Unity 2021.3.41f1 LTS) Unity uaktualniło dołączony łańcuch narzędzi do wersji AGP 7.1.2+, usunęło obsługę starszej wersji ProGuard i uruchamia wyłącznie R8, gdy włączona jest minifikacja.

Wersja Unity Połączone AGP Zwolnij domyślne Obsługa R8 i wymagana konfiguracja
2019.4 LTS i starsze Wcześniej niż 3.4 Wyłączone (false) Nieobsługiwane (tyl starsza wersja ProGuard).
od 2020.1.0f1 do 2021.3.40f1 3,4–4,0 Wyłączone (false) Opcjonalne (domyślnie ProGuard). Włącz opcje Minify > Release (Zmniejsz > Wersja) i Use R8 (Użyj R8).
2021.3.41f1 i nowsze (2021 LTS) 7.1+ Wyłączone (false) Tylko R8. Włącz Minify > Release (Zmniejsz > Wersja), aby automatycznie uruchamiać R8.
2022.2.0f1 do Unity 6+ 7.1–8.x Wyłączone (false) Tylko R8. Włącz Minify > Release (Zmniejsz > Wersja), aby automatycznie uruchamiać R8.

Włączanie R8 w ustawieniach odtwarzacza

Aby włączyć zmniejszanie i optymalizację kodu R8 w przypadku kompilacji do publikacji:

  1. W edytorze Unity kliknij Edit > Project Settings (Edytuj > Ustawienia projektu) i wybierz Player (Odtwarzacz).
  2. Wybierz kartę Android i rozwiń Publishing Settings > Build (Ustawienia publikowania > Kompilacja).
  3. W sekcji Minify (Zmniejsz) skonfiguruj opcje dla swojej wersji Unity:
    • Unity 2021.3.41f1 lub nowsza i 2022.2.0f1 lub nowsza: wybierz Release (Wersja). Unity automatycznie uruchamia R8 podczas zadania Gradle minifyReleaseWithR8.
    • Unity w wersjach od 2020.1.0f1 do 2021.3.40f1: wybierz zarówno Release (Wersja), jak i Use R8 (Użyj R8).

Jeśli automatyzujesz kompilacje za pomocą skryptów edytora C#, skonfiguruj te właściwości za pomocą 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
    }
}

Dodawanie reguł zachowywania dla JNI i refleksji

Klasy i metody Javy wywoływane dynamicznie ze skryptów C# za pomocą AndroidJavaClass lub AndroidJavaObject nie mają statycznych miejsc wywołania Javy. Bez wyraźnych reguł zachowywania R8 może uznać te klasy za nieużywane i usunąć je lub zmienić ich nazwy.

Aby zachować niestandardowe mosty Java:

  1. W sekcji Project Settings > Player > Android > Publishing Settings > Build (Ustawienia projektu > Odtwarzacz > Android > Ustawienia publikowania > Kompilacja) włącz Custom Proguard File (Niestandardowy plik Proguard).
  2. Otwórz wygenerowany plik Assets/Plugins/Android/proguard-user.txt.
  3. Dodaj reguły -keep dla klas, do których dostęp jest uzyskiwany przez JNI lub które są wymagane przez wtyczki innych firm:
# 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 { *; }

Rozwiązywanie typowych problemów

W tej sekcji opisano, jak rozwiązywać typowe problemy z kompilacją i środowiskiem wykonawczym podczas korzystania z R8 w Unity.

Błędy kompilacji: Missing classes detected while running R8

W wersjach Unity korzystających z wtyczki Androida do obsługi Gradle w wersji 7.0 lub nowszej (2021.3.41f1+ i 2022.2+) R8 wymusza rygorystyczne sprawdzanie brakujących klas. Jeśli kompilacja nie powiedzie się z powodu tego błędu, sprawdź wygenerowany plik missing_rules.txt w katalogu wyjściowym kompilacji (w Library/Bee/Android/Prj/.../build/outputs/mapping/release/missing_rules.txt lub Temp/gradleOut/...) i dodaj wymagane zależności lub reguły do proguard-user.txt. Więcej informacji o tworzeniu reguł zachowywania znajdziesz w artykule Dostosowywanie kodu do zachowania.

Zgodność trybu pełnego R8 z wtyczkami innych firm

W AGP 8.0 i nowszych (Unity 6+) tryb pełny R8 jest domyślnie włączony, aby przeprowadzać bardziej agresywne optymalizacje. Jeśli starsza wtyczka Androida nie działa w czasie działania z powodu problemów z refleksją, zaktualizuj reguły ProGuard wtyczki lub przywróć tryb zgodności R8:

  1. W sekcji Publishing Settings > Build (Ustawienia publikowania > Kompilacja) włącz Custom Gradle Properties Template (Niestandardowy szablon właściwości Gradle).
  2. Otwórz plik Assets/Plugins/Android/gradleTemplate.properties i dodaj tę właściwość:
android.enableR8.fullMode=false