Otimize o desempenho do seu jogo para dispositivos móveis: Obtenha dicas de especialistas sobre física, interface do usuário e configurações de áudio

Nossa equipe de Sucesso Integrado oferece suporte aos clientes da Unity com seus problemas técnicos complexos. Conversamos com essa equipe de engenheiros de software sênior e pedimos que eles compartilhassem um pouco de sua experiência em otimização de jogos para dispositivos móveis.
Nossa equipe Accelerate Solutions conhece profundamente o código-fonte e trabalha com diversos clientes da Unity para ajudá-los a aproveitar ao máximo o mecanismo. Em seu trabalho, eles se aprofundam nos projetos dos criadores para ajudar a identificar pontos onde o desempenho pode ser otimizado para maior velocidade, estabilidade e eficiência.
À medida que nossos engenheiros começaram a compartilhar suas ideias sobre otimização de jogos para dispositivos móveis, percebemos rapidamente que havia muita informação boa para uma única postagem de blog que havíamos planejado. Em vez disso, decidimos transformar essa montanha de conhecimento em um e-book completo (que você pode baixar aqui), bem como em uma série de postagens de blog que destacam algumas dessas mais de 75 dicas práticas.
Nesta segunda parte desta série, vamos nos concentrar em como melhorar o desempenho com a interface do usuário, a física e as configurações de áudio. Caso você tenha perdido, confira nossa postagem anterior sobre criação de perfil, memória e arquitetura de código – e fique ligado na próxima, dedicada a ativos, configuração de projeto e gráficos.
Quer tudo agora? Baixe o e-bookgratuito.
Vamos direto ao assunto!
O Physics integrado do Unity (Nvidia PhysX) pode ser caro em dispositivos móveis, mas as dicas a seguir podem ajudar você a extrair mais quadros por segundo.
Em PlayerSettings, marque Prebake Collision Meshes sempre que possível.

Certifique-se de editar suas configurações de Física (Configurações do Projeto > Física) e simplificar sua Matriz de Colisão de Camadas sempre que possível.
Desabilite as transformações de sincronização automática e habilite a reutilização de retornos de chamada de colisão.


Os aceleradores de malha podem ser caros. Substitua colisores de malha mais complexos por colisores de malha primitivos ou simplificados para aproximar o formato original.

Use métodos de classe como MovePosition ou AddForce para mover seus objetos Rigidbody . Traduzir seus componentes Transform diretamente pode levar a recálculos do mundo físico, o que é caro em cenas complexas. Mova os corpos físicos em FixedUpdate em vez de Update.
O intervalo de tempo fixo padrão nas configurações do projeto é 0,02 (50 Hz). Altere isso para corresponder à sua taxa de quadros alvo (por exemplo, 0,03 para 30 fps).
No entanto, se sua taxa de quadros cair em tempo de execução, isso significa que o Unity chamaria FixedUpdate várias vezes por quadro e potencialmente criaria um problema de desempenho da CPU com conteúdo com muita física.
O intervalo de tempo máximo permitido limita quanto tempo os cálculos de física e os eventos FixedUpdate podem usar no caso de queda da taxa de quadros. Reduzir esse valor significa que, durante uma queda de desempenho, a física e a animação podem ficar mais lentas, reduzindo também seu impacto na taxa de quadros.

Use a janela Depuração de física (Janela > Análise > Depurador de física) para ajudar a solucionar problemas de colisão ou discrepâncias. Isso mostra um indicador codificado por cores dos GameObjects que podem colidir uns com os outros.

Para obter mais informações, consulte Visualização de depuração de física na documentação do Unity .
A Unity UI (UGUI) pode frequentemente ser uma fonte de problemas de desempenho. O componente Canvas gera e atualiza malhas para os elementos da interface do usuário e emite chamadas de desenho para a GPU. Seu funcionamento pode ser caro, portanto, tenha em mente os seguintes fatores ao trabalhar com o UGUI.
Se você tiver um Canvas grande com milhares de elementos, atualizar um único elemento da interface do usuário forçará todo o Canvas a ser atualizado, o que pode gerar um pico de CPU.
Aproveite a capacidade do UGUI de oferecer suporte a vários Canvas. Divida os elementos da interface do usuário com base na frequência com que eles precisam ser atualizados. Mantenha elementos estáticos da interface do usuário em uma tela separada e elementos dinâmicos que são atualizados ao mesmo tempo em subtelas menores.
Certifique-se de que todos os elementos da interface do usuário em cada tela tenham o mesmo valor Z, materiais e texturas.
Você pode ter elementos de interface do usuário que só aparecem esporadicamente no jogo (por exemplo, uma barra de saúde que aparece quando um personagem sofre dano). Se o seu elemento de interface de usuário invisível estiver ativo, ele ainda poderá estar usando chamadas de desenho. Desative explicitamente quaisquer componentes invisíveis da interface do usuário e reative-os conforme necessário.
Se você só precisa desativar a visibilidade do Canvas, desative o componente Canvas em vez do GameObject. Isso pode economizar a reconstrução de malhas e vértices.
Eventos de entrada, como toques ou cliques na tela, exigem o componente GraphicRaycaster . Isso simplesmente percorre cada ponto de entrada na tela e verifica se ele está dentro do RectTransform da IU.
Remova o GraphicRaycaster padrão do Canvas superior na hierarquia. Em vez disso, adicione o GraphicRaycaster exclusivamente aos elementos individuais que precisam interagir (botões, scrollrects e assim por diante).

Além disso, desative o Raycast Target em todos os textos e imagens da interface do usuário que não precisam dele. Se a interface do usuário for complexa com muitos elementos, todas essas pequenas alterações podem reduzir cálculos desnecessários.

Os grupos de layout são atualizados de forma ineficiente, portanto, use-os com moderação. Evite-os completamente se seu conteúdo não for dinâmico e use âncoras para layouts proporcionais. Caso contrário, crie um código personalizado para desabilitar os componentes do Layout Group depois que eles configurarem a IU.
Se você precisar usar Grupos de Layout (Horizontal, Vertical, Grade) para seus elementos dinâmicos, evite aninhá-los para melhorar o desempenho.

Visualizações de lista e grade grandes são caras. Se você precisar criar uma grande exibição de Lista ou Grade (por exemplo, uma tela de inventário com centenas de itens), considere reutilizar um conjunto menor de elementos de IU em vez de criar um elemento de IU para cada item. Confira este projeto de exemplo do GitHub para ver isso em ação.
Sobrepor muitos elementos da interface do usuário (por exemplo, cartas empilhadas em um jogo de batalha de cartas) cria um overdraw. Personalize seu código para mesclar elementos em camadas no tempo de execução em menos elementos e lotes.
Com os dispositivos móveis agora usando resoluções e tamanhos de tela muito diferentes, crie versões alternativas da interface do usuário para oferecer a melhor experiência em cada dispositivo.
Use o Simulador de Dispositivos para visualizar a interface do usuário em uma ampla variedade de dispositivos suportados. Você também pode criar dispositivos virtuais no XCode e no Android Studio.

Se a tela de pausa ou início cobrir todo o resto da cena, desative a câmera que está renderizando a cena 3D . Da mesma forma, desabilite quaisquer elementos de fundo do Canvas ocultos atrás do Canvas superior.
Considere diminuir o Application.targetFrameRate durante uma interface de usuário em tela cheia, já que você não precisa atualizar a 60 fps.
Deixar o campo Evento ou Câmera de Renderização em branco força o Unity a preencher Camera.main, o que é desnecessariamente caro.
Considere usar Screen Space – Overlay para seu Canvas RenderMode , se possível, pois isso não requer uma câmera.

Embora o áudio normalmente não seja um gargalo de desempenho, você ainda pode otimizar para economizar memória.

Se você usar qualquer formato compactado (como MP3 ou Vorbis), o Unity irá descompactá-lo e depois compactá-lo novamente durante o tempo de compilação. Isso resulta em duas passagens com perdas, degradando a qualidade final.
Reduza o tamanho dos seus clipes e o uso de memória com compactação:
- Use Vorbis para a maioria dos sons (ou MP3 para sons que não devem ser reproduzidos em loop).
- Use ADPCM para sons curtos e usados com frequência (por exemplo, passos, tiros). Isso reduz os arquivos em comparação ao PCM não compactado, mas é rápido de decodificar durante a reprodução.
Os efeitos sonoros em dispositivos móveis devem ter no máximo 22.050 Hz. Usar configurações mais baixas geralmente tem impacto mínimo na qualidade final; use seus próprios ouvidos para julgar.
A configuração varia de acordo com o tamanho do clipe.
- Pequenos clipes (< 200 kb) devem Descomprimir ao carregar. Isso gera custos de CPU e memória ao descompactar um som em dados de áudio PCM brutos de 16 bits, por isso é desejável apenas para sons curtos.
- Clipes médios (>= 200 kb) devem permanecer compactados na memória.
- Arquivos grandes (música de fundo) devem ser definidos como Streaming, caso contrário, todo o recurso será carregado na memória de uma só vez.
Ao implementar um botão de mudo, não defina simplesmente o volume como 0. Você pode destruir o componente AudioSource para descarregá-lo da memória, desde que o player não precise ativar e desativar isso com muita frequência.
Na próxima postagem do blog, falaremos diretamente sobre gráficos e ativos. Mas se você quiser ter acesso à lista completa de dicas e truques da equipe hoje, nosso e-book completo está disponível aqui.

Se você estiver interessado em saber mais sobre os serviços de Suporte Integrado e quiser dar à sua equipe acesso direto a engenheiros, consultoria especializada e orientação de melhores práticas para seus projetos, confira os planos de sucesso da Unity aqui.
Queremos ajudar você a tornar seus aplicativos Unity o mais eficientes possível. Portanto, se houver algum tópico de otimização sobre o qual você gostaria de saber mais, mantenha-nos informados nos comentários.