Reduzir e otimizar o código do Unity com o R8

Embora a lógica principal do jogo no Unity seja escrita em C# (compilada com IL2CPP), as versões do Android incluem um bytecode Java e Kotlin substancial (classes.dex) para processar eventos de ciclo de vida do UnityPlayerActivity, o Google Play Services, o faturamento, os anúncios e os SDKs sociais.

Ativar o R8, o redutor e otimizador de código padrão no Plug-in do Android para Gradle (AGP), remove classes e métodos não utilizados e otimiza o bytecode. Isso não apenas diminui o tamanho do download do app, mas também reduz o consumo de memória em tempo de execução das páginas DEX mapeadas na memória (mmap) e a sobrecarga do processo Java de referência, mitigando a pressão da memória física e as finalizações do low memory killer (LMK). O Google Play também monitora os níveis de otimização de DEX do seu jogo com a métrica Otimização de código DEX no Android vitals.

Comportamento padrão e suporte à versão do Unity

No Unity, a minificação de código é desativada por padrão (false) para builds de lançamento e builds de depuração ao criar um novo projeto.

O Unity introduziu o R8 como uma opção no Unity 2020.1.0f1. A partir do Unity 2022.2.0f1 (e com backport para o Unity 2021.3.41f1 LTS), o Unity atualizou o conjunto de ferramentas incluído para o AGP 7.1.2+, removeu o suporte legado ao ProGuard e executa o R8 exclusivamente sempre que a minificação está ativada.

Versão do Unity AGP em pacote Versão padrão Suporte ao R8 e configuração necessária
2019.4 LTS e anteriores Anterior à 3.4 Desativado (false) Não compatível (somente ProGuard legado).
2020.1.0f1 a 2021.3.40f1 3.4 a 4.0 Desativado (false) Opcional (o padrão é ProGuard). Ative as opções Minify > Release e Use R8.
2021.3.41f1 e versões mais recentes (2021 LTS) 7.1+ Desativado (false) Somente R8. Ative Minify > Release para executar o R8 automaticamente.
2022.2.0f1 para Unity 6+ 7.1 a 8.x Desativado (false) Somente R8. Ative Minify > Release para executar o R8 automaticamente.

Ativar o R8 nas configurações do player

Para ativar a redução de código e a otimização do R8 para builds de lançamento:

  1. No Unity Editor, abra Edit > configurações do projeto e selecione Player.
  2. Selecione a guia Android e abra Publishing Settings > Build.
  3. Na seção Minify, configure as opções para sua versão do Unity:
    • Unity 2021.3.41f1+ e 2022.2.0f1+: selecione Release. O Unity executa o R8 automaticamente durante a tarefa minifyReleaseWithR8 do Gradle.
    • Unity 2020.1.0f1 a 2021.3.40f1: selecione Release e Use R8.

Se você automatizar builds usando scripts do editor em C#, configure essas propriedades com 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
    }
}

Adicionar regras de manutenção para JNI e reflexão

As classes e os métodos Java invocados dinamicamente de scripts C# usando AndroidJavaClass ou AndroidJavaObject não têm sites de chamada Java estáticos. Sem regras de manutenção explícitas, o R8 pode considerar essas classes não utilizadas e removê-las ou renomeá-las.

Para preservar suas pontes Java personalizadas:

  1. Em Configurações do projeto > Player > Android > Publishing Settings > Build, ative Custom Proguard File.
  2. Abra o arquivo Assets/Plugins/Android/proguard-user.txt gerado.
  3. Adicione regras -keep para classes acessadas pela JNI ou exigidas por plug-ins de terceiros:
# 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 { *; }

Solução de problemas comuns

Nesta seção, descrevemos como resolver problemas comuns de build e de execução ao usar o R8 no Unity.

Missing classes detected while running R8 erro de build

Nas versões do Unity que usam o AGP 7.0 e mais recentes (2021.3.41f1+ e 2022.2+), o R8 aplica verificações rigorosas de classes ausentes. Se uma build falhar com esse erro, inspecione o arquivo missing_rules.txt gerado no diretório de saída da build (em Library/Bee/Android/Prj/.../build/outputs/mapping/release/missing_rules.txt ou Temp/gradleOut/...) e adicione as dependências ou regras necessárias a proguard-user.txt. Para mais informações sobre como escrever regras de manutenção, consulte Personalizar o código a ser mantido.

Compatibilidade do modo completo do R8 com plug-ins de terceiros

No AGP 8.0 e versões mais recentes (Unity 6+), o modo completo do R8 é ativado por padrão para realizar otimizações mais agressivas. Se um plug-in legado do Android falhar no momento da execução devido a problemas de reflexão, atualize as regras do ProGuard do plug-in ou reverta o R8 para o modo de compatibilidade:

  1. Em Publishing Settings > Build, ative Custom Gradle Properties Template.
  2. Abra Assets/Plugins/Android/gradleTemplate.properties e adicione a seguinte propriedade:
android.enableR8.fullMode=false