Esta é uma das várias páginas que fornecem orientações detalhadas sobre como otimizar os jogos para PC e console. Você pode encontrar a coleção completa no e-book gratuito, Otimize o desempenho dos jogos para console e PCrepleto de mais de 80 dicas práticas e práticas recomendadas para otimização do desempenho.
Problema: Quando um único elemento é alterado no Canvas da interface do usuário, ele suja todo o Canvas.
O Canvas é o componente básico da interface do usuário do Unity. Ele gera malhas que representam os elementos da interface do usuário colocados nele, regenera as malhas quando os elementos da interface do usuário são alterados e emite chamadas de desenho para a GPU para que a interface do usuário seja realmente exibida.
A geração dessas malhas pode ser cara. Os elementos da interface do usuário precisam ser coletados em lotes para que sejam desenhados no menor número possível de chamadas de desenho. Como a geração de lotes é cara, queremos regenerá-los somente quando necessário. O problema é que, quando um ou mais elementos mudam em um Canvas, todo o Canvas precisa ser analisado mais uma vez para descobrir como desenhar seus elementos de forma ideal.
Muitos usuários criam toda a interface do usuário do jogo em um único Canvas com milhares de elementos. Quando eles alteram um elemento, podem experimentar um pico de CPU que custa vários milissegundos. Para saber mais sobre por que a reconstrução é tão cara, vá para a marca de 24:55 nesta sessão da Unite.
Solução Divida suas telas.
Cada Canvas é uma ilha que isola seus elementos dos de outros Canvases. Aproveite a capacidade do UGUI de oferecer suporte a vários Canvases, dividindo seus Canvases para resolver os problemas de lote com a interface do usuário do Unity.
Também é possível aninhar Canvases, o que permite que os designers criem grandes interfaces de usuário hierárquicas, sem precisar pensar em onde os diferentes elementos estão na tela em todos os Canvases. Os Canvases filhos também isolam o conteúdo de seus Canvases pais e irmãos. Eles mantêm sua própria geometria e realizam sua própria dosagem. Uma maneira de decidir como dividi-los é com base na frequência com que eles precisam ser atualizados. Mantenha os elementos estáticos da interface do usuário em uma tela separada e os elementos dinâmicos que são atualizados ao mesmo tempo em subtelas menores. Além disso, certifique-se de que todos os elementos da interface do usuário em cada tela tenham o mesmo valor Z, materiais e texturas.
Problema: Uso inadequado do Graphic Raycaster
O Graphic Raycaster é o componente que converte sua entrada em eventos da interface do usuário. Mais especificamente, ele traduz os cliques na tela ou as entradas de toque na tela em eventos da interface do usuário e os envia para os elementos da interface do usuário interessados. Você precisa de um Graphic Raycaster em cada tela que requer entrada, incluindo subcanvas. No entanto, ele também percorre todos os pontos de entrada na tela e verifica se eles estão dentro de uma RectTransform da UI, resultando em uma possível sobrecarga.
Apesar de seu nome, o Graphic Raycaster não é realmente um raycaster. Por padrão, ele testa apenas os gráficos da interface do usuário. Ele pega o conjunto de elementos da interface do usuário que estão interessados em receber entrada em um determinado Canvas e realiza verificações de interseção. Por exemplo, ele verifica se o ponto em que o evento de entrada ocorre em relação ao RectTransform de cada elemento da interface do usuário na tela do Graphic Raycaster está marcado como interativo.
O desafio é que nem todos os UI Elements estão interessados em receber atualizações.
Solução Remova os Raycasters gráficos das telas de IU não interativas e desative o Raycast Target para elementos estáticos ou não interativos.
Em particular, o texto em um botão que desativa o Raycast Target reduzirá diretamente o número de verificações de interseção que o Raycaster gráfico deve executar em cada quadro.
Problema: Às vezes, o Graphic Raycaster funciona como um raycaster.
Se você definir o modo de renderização no Canvas como Worldspace Camera ou Screen Space Camera, poderá adicionar uma máscara de bloqueio. A máscara de bloqueio determina se o Raycaster lançará raios por meio de física 2D ou 3D, para determinar se algum objeto de física está bloqueando a capacidade do usuário de interagir com a interface do usuário.
Solução O lançamento de raios por meio de física 2D ou 3D pode ser caro, portanto, use esse recurso com moderação.
Minimize o número de Raycasters gráficos excluindo-os de telas de interface do usuário não interativas, pois, nesse caso, não há motivo para verificar se há eventos de interação.
Saiba mais sobre o Graphic Raycaster nesta documentação.
Problema: Lista grande, exibições de grade e vários elementos de IU sobrepostos são caros.
As exibições grandes de lista e grade são caras, e a disposição em camadas de vários elementos da interface do usuário (por exemplo, cartas empilhadas em um jogo de batalha de cartas) cria um excesso de desenho.
Solução Evite vários elementos de IU sobrepostos.
Personalize seu código para mesclar elementos de interface do usuário em camadas no tempo de execução em menos elementos e lotes.
Se precisar criar uma exibição de lista ou grade grande, como uma tela de inventário com centenas de itens, considere a possibilidade de reutilizar um conjunto menor de elementos de interface do usuário em vez de um único elemento de interface do usuário para cada item.
Confira este projeto do GitHub para ver um exemplo de uma lista de rolagem otimizada.
Problema: Todo elemento da interface do usuário que tentar sujar seu layout executará pelo menos uma chamada GetComponent.
Quando um ou mais elementos de IU filhos são alterados em um sistema de layout, o layout fica "sujo". O(s) elemento(s) filho(s) alterado(s) invalida(m) o sistema de layout que o possui.
Um sistema de layout é um conjunto de grupos de layout contíguos diretamente acima de um elemento de layout. Um elemento de layout não é apenas o componente Elemento de layout (imagens da interface do usuário, textos e Scroll Rects), ele também inclui elementos de layout, assim como Scroll Rects também são grupos de layout.
Agora, com relação ao problema em questão: Todo elemento da interface do usuário que marcar seu layout como "sujo" executará, no mínimo, uma chamada GetComponent. Essa chamada procura um grupo de layout válido no pai do elemento de layout. Se encontrar um, ele continua subindo na hierarquia Transform até parar de procurar grupos de layout ou chegar à raiz da hierarquia, o que ocorrer primeiro. Dessa forma, cada grupo de layout adiciona uma chamada GetComponent ao processo de sujeira de cada elemento de layout filho, o que torna os grupos de layout aninhados extremamente ruins para o desempenho.
Solução Evite grupos de layout sempre que possível.
Use Anchors para layouts proporcionais. Em UIs quentes com um número dinâmico de elementos de UI, considere escrever seu próprio código para calcular layouts. Certifique-se de usá-lo sob demanda, e não para cada alteração.
Saiba mais sobre grupos de layout em nossa documentação.
Problema: Agrupamento de objetos da interface do usuário da maneira errada
As pessoas costumam agrupar objetos da interface do usuário reparentando-os e depois desativando-os, o que causa sujeira desnecessária.
Solução Desative o objeto primeiro e, em seguida, reenvie-o para o pool.
Você sujará a hierarquia antiga uma vez, mas, depois de repará-la, evitará sujar a hierarquia antiga uma segunda vez e não sujará a nova hierarquia. Se estiver removendo um objeto do pool, repare-o primeiro, atualize seus dados e, em seguida, ative-o.
Saiba mais sobre os conceitos de pooling básico de objetos no Unity.
Problema: Não tem certeza de como ocultar um Canvas
Às vezes, é útil ocultar os elementos da interface do usuário e as telas. Mas como você pode fazer isso de forma eficiente?
Solução Desativar o próprio componente Canvas.
A desativação do componente Canvas impedirá que o Canvas emita chamadas de desenho para a GPU. Dessa forma, o Canvas não ficará mais visível. No entanto, o Canvas não descartará seu buffer de vértice, ele manterá todas as suas malhas e vértices. Então, quando você reativá-lo, ele não acionará uma reconstrução, apenas começará a desenhá-los novamente.
Além disso, a desativação do componente Canvas não aciona as dispendiosas chamadas de retorno OnDisable/OnEnable por meio da hierarquia do Canvas. Apenas tome cuidado para desativar os componentes filhos que executam códigos caros por quadro.
Saiba mais sobre o componente Canvas aqui.
Problema: Uso de animadores em sua interface do usuário
Os animadores sujarão os elementos da interface do usuário em cada quadro, mesmo que o valor da animação não seja alterado.
Solução Use o código para animação da interface do usuário.
Coloque animadores apenas em elementos dinâmicos da interface do usuário que sempre mudam. Para elementos que raramente mudam ou que mudam temporariamente em resposta a eventos, escreva seu próprio código ou use um sistema de interpolação. Há várias soluções excelentes para isso disponíveis na Asset Store.
Problema: Desempenho insatisfatório com a interface do usuário em tela cheia
Se o seu jogo exibir uma tela de pausa ou inicial que cubra totalmente a cena, o restante do jogo ainda estará sendo renderizado em segundo plano, o que pode afetar o desempenho.
Solução Esconda todo o resto.
Se você tiver uma tela que cubra todo o resto da cena, desative a câmera que renderiza a cena 3D. Da mesma forma, desative os elementos do Canvas ocultos atrás do Canvas superior.
Considere a possibilidade de reduzir o Application.targetFrameRate durante uma interface de usuário em tela cheia, pois não é necessário atualizar a 60 fps.
Ofereça aos seus jogadores a melhor experiência de jogo possível. Com mais de 80 dicas práticas e práticas recomendadas dos engenheiros especialistas da Unity, você pode otimizar seus jogos para PC e console.
Criadas pelas equipes de engenharia do Unity Success e Accelerate Solutions, mais especificamente, essas práticas detalhadas - reunidas a partir de compromissos reais com os principais estúdios - ajudarão a aumentar o desempenho geral do seu jogo.