Attention: Here be dragons

This is the latest (unstable) version of this documentation, which may document features not available in or compatible with released stable versions of Godot.

Otimizando o desempenho da navegação

../../_images/nav_optimization.webp

Os problemas comuns de desempenho relacionados à navegação podem ser categorizados nos seguintes tópicos:

  • Problemas de desempenho com a análise (parsing) de nós da árvore de cenas para a geração de malha de navegação.

  • Problemas de desempenho com a geração da malha de navegação propriamente dita.

  • Problemas de desempenho com consultas de caminho de NavigationAgent.

  • Problemas de desempenho com a busca de caminho propriamente dita.

  • Problemas de desempenho com a sincronização do mapa de navegação.

Nas seções seguintes, podem ser encontradas informações sobre como identificar e corrigir ou, pelo menos, mitigar o impacto deles nas taxas de quadros (framerate).

Problemas de desempenho com a análise de nós da árvore de cenas

Dica

Prefira usar formas simples com o menor número possível de arestas, por exemplo, nada arredondado como um círculo, esfera ou toro.

Prefira usar formas de colisão de física em vez de malhas visuais complexas como geometria de origem, pois as malhas precisam ser copiadas da GPU e geralmente são muito mais detalhadas do que o necessário.

Em geral, evite usar geometrias muito complexas como geometria de origem para o baking de malhas de navegação. Por exemplo, nunca use uma malha visual muito detalhada, pois analisar sua forma em arrays de dados e voxelizá-la para o baking da malha de navegação levará muito tempo sem proporcionar nenhum ganho significativo na qualidade da malha de navegação final. Em vez disso, use uma versão da forma com um nível de detalhe bastante simplificado. Melhor ainda, use formas bem simples, como caixas e retângulos, que apenas cubram aproximadamente a mesma geometria, mas ainda produzam um resultado de baking suficientemente bom para o cálculo de caminhos.

Prefira usar formas simples de colisão de física em vez de malhas visuais como geometria de origem para o pré-cálculo de malhas de navegação (navigation meshes). As formas de física, por padrão, são formas muito limitadas e otimizadas, fáceis e rápidas de analisar. Já uma malha visual pode variar de simples a complexa. Além disso, para ter acesso aos dados da malha visual, o analisador precisa solicitar os arrays de dados da malha ao Servidor de Renderização (RenderingServer), já que os dados da malha visual são armazenados diretamente na GPU e não ficam em cache na CPU. Isso exige bloquear a thread do RenderingServer e pode afetar severamente a taxa de quadros em tempo de execução enquanto a renderização roda em múltiplas threads. Se a renderização rodar em uma única thread, o impacto na taxa de quadros pode ser ainda pior e a análise da malha pode travar o jogo inteiro por alguns segundos em malhas complexas.

Problemas de desempenho com a geração de malha de navegação

Dica

Em tempo de execução, prefira sempre usar uma thread de segundo plano (background thread) para gerar malhas de navegação.

Aumente o cell_size e o cell_height da NavigationMesh para criar menos voxels.

Altere o SamplePartitionType de watershed para monotone ou layers para obter mais desempenho na geração.

Aviso

NUNCA redimensione (scale) a geometria de origem com nós para evitar erros de precisão. A maior parte do redimensionamento aplica-se apenas visualmente, e formas que são muito grandes em sua escala base ainda exigem muito processamento extra mesmo quando reduzidas.

A geração de malhas de navegação em tempo de execução deve sempre ser feita em uma thread de segundo plano, se possível. Mesmo malhas de navegação de tamanho pequeno podem levar muito mais tempo para serem geradas do que o que é possível espremer em um único quadro, pelo menos se a taxa de quadros deve se manter em um nível aceitável.

A complexidade dos dados de geometria de origem analisados a partir dos nós da árvore da cena tem grande impacto no desempenho do bake, pois tudo precisa ser mapeado para uma grade / voxels. Para desempenho de bake em tempo de execução, o tamanho da célula e a altura da célula da NavigationMesh (Malha de Navegação)devem ser definidos o mais altos possível sem causar problemas de qualidade na malha de navegação do jogo. Se o tamanho ou a altura da célula forem definidos muito baixos, o pré-cálculo é forçado a criar uma quantidade excessiva de voxels para processar a geometria de origem. Se a geometria de origem se estender por um mundo de jogo muito grande, é até possível que o processo do pré-cálculo fique sem memória no meio e faça o jogo travar. O tipo de partição também pode ser reduzido dependendo de quão complexa é a geometria de origem do jogo para ganhar desempenho. Por exemplo, jogos com superfícies majoritariamente planas e geometria em blocos podem usar o modo monotone ou layers, que são muito mais rápidos de gerar (por exemplo, porque não exigem uma etapa de campo de distância).

Nunca redimensione a geometria de origem com nós. Isso não apenas pode resultar em muitos erros de precisão com vértices e arestas mal correspondidos, mas também alguns redimensionamentos existem apenas visualmente e não nos dados analisados reais. Por exemplo, se uma malha for reduzida visualmente no Editor, com a escala definida para 0.001 em uma MeshInstance, a malha ainda exigirá uma grade de voxels gigantesca e muito complexa para ser processada na geração.

Problemas de desempenho com consultas de caminho de NavigationAgent

Dica

Evite resets de caminho desnecessários e consultas a cada quadro nos scripts de NavigationAgent.

Evite atualizar todos os caminhos de NavigationAgent no mesmo quadro.

Erros lógicos e operações desnecessárias nos scripts personalizados de NavigationAgent são causas muito comuns de problemas de desempenho, por exemplo, preste atenção para não resetar o caminho a cada quadro. Por padrão, os NavigationAgents são otimizados para consultar novos caminhos apenas quando a posição de destino muda, o mapa de navegação muda ou se eles forem forçados para muito longe da distância desejada do caminho.

Por exemplo, quando uma IA deve se mover em direção ao jogador, a posição de destino não deve ser definida para a posição do jogador a cada quadro, pois isso consulta um novo caminho a cada quadro. Em vez disso, a distância da posição de destino atual até a posição do jogador deve ser comparada e, somente quando o jogador tiver se movido para muito longe, uma nova posição de destino deve ser definida.

Não verifique de antemão se uma posição de destino é alcançável a cada quadro. O que parece ser uma verificação inofensiva é o equivalente a uma consulta de caminho dispendiosa nos bastidores. Se o plano for solicitar um novo caminho de qualquer forma caso a posição seja alcançável, um caminho deve ser consultado diretamente. Ao olhar para a última posição do caminho retornado, e se essa posição estiver a uma distância "alcançável" da posição verificada, isso responde à pergunta "esta posição é alcançável?". Isso evita fazer o equivalente a duas consultas de caminho completas a cada quadro para o mesmo NavigationAgent.

Divida o número total de NavigationAgents em grupos de atualização ou use temporizadores (timers) aleatórios para que nem todos solicitem novos caminhos no mesmo quadro.

Problemas de desempenho com a sincronização do mapa de navegação

Dica

Mescle os polígonos das malhas de navegação por vértices em vez de por conexão de arestas sempre que possível.

Quando são feitas alterações em, por exemplo, malhas de navegação ou regiões de navegação, o NavigationServer precisa sincronizar o mapa de navegação. Dependendo da complexidade das malhas de navegação, isso pode levar um tempo significativo, o que pode impactar a taxa de quadros.

O NavigationServer mescla as malhas de navegação por vértice ou por conexão de aresta. A mesclagem por vértice acontece quando os dois vértices de duas arestas diferentes caem nas mesmas células da grade do mapa. Esta é uma operação bastante rápida e de baixo custo. A mesclagem por conexão de aresta acontece em um segundo passo para todas as arestas que ainda não foram mescladas. Todas as arestas livres são verificadas quanto a possíveis conexões de aresta tanto por distância quanto por ângulo, o que é bastante dispendioso.

Portanto, além da regra geral de ter o menor número possível de arestas de polígonos, o maior número possível de arestas deve ser mesclado por vértice de antemão, para que restem apenas algumas arestas para o cálculo mais dispendioso de conexão de aresta. O monitor de depuração Navigation PerformanceMonitor pode ser usado para obter estatísticas sobre quantos polígonos e arestas estão disponíveis e quantos deles não estão mesclados ou não estão mesclados por vértice. Se a proporção entre vértices mesclados e conexões de aresta estiver muito desequilibrada (os vértices devem ser significativamente maiores), as malhas de navegação foram criadas de forma inadequada ou posicionadas de maneira muito ineficiente.