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.
Checking the stable version of the documentation...
Usando malhas de navegação
As versões 2D e 3D da malha de navegação estão disponíveis como NavigationPolygon e NavigationMesh, respectivamente.
Nota
Uma malha de navegação apenas descreve uma área atravessável para a posição central de um agente. Quaisquer valores de raio que um agente possa ter são ignorados. Se você deseja que a busca de caminhos leve em consideração o tamanho (de colisão) de um agente, você precisa encolher a malha de navegação de acordo.
A navegação funciona de forma independente de outras partes da engine, como renderização ou física. As malhas de navegação são as únicas coisas consideradas ao fazer a busca de caminhos; por exemplo, os visuais e as formas de colisão são completamente ignorados pelo sistema de navegação. Se você precisar levar outros dados em consideração (como os visuais, por exemplo) ao fazer a busca de caminhos, precisará adaptar suas malhas de navegação de acordo. O processo de fatorar as restrições de navegação nas malhas de navegação é comumente chamado de geração (baking) de malha de navegação.
Uma malha de navegação descreve uma superfície na qual um agente pode ficar de pé com segurança com o seu centro, em comparação com as formas físicas que descrevem os limites externos de colisão.
Se você tiver problemas de recorte (clipping) ou colisão ao seguir caminhos de navegação, lembre-se sempre de que você precisa dizer ao sistema de navegação quais são as suas intenções por meio de uma malha de navegação apropriada. Por si só, o sistema de navegação nunca saberá "isto é uma forma de colisão de árvore / rocha / parede ou uma malha visual", porque ele apenas sabe que "aqui me disseram que posso seguir o caminho com segurança porque está em uma malha de navegação".
A geração de malha de navegação pode ser feita usando um NavigationRegion2D ou NavigationRegion3D, ou usando a API do NavigationServer2D e NavigationServer3D diretamente.
Gerando uma malha de navegação com uma NavigationRegion
Gerando uma malha de navegação com deslocamento do raio do agente a partir da geometria.
A geração de malha de navegação tornou-se mais acessível com o nó NavigationRegion. Ao gerar com um nó NavigationRegion, as etapas individuais de análise (parsing), geração (baking) e atualização de região são combinadas em uma única função.
Os nós estão disponíveis em 2D e 3D como NavigationRegion2D e NavigationRegion3D, respectivamente.
Dica
O source_geometry_mode da malha de navegação pode ser alterado para analisar nomes de grupos de nós específicos, de modo que os nós que devem ser gerados possam ser colocados em qualquer lugar da cena.
Quando um nó NavigationRegion2D é selecionado no Editor, as opções de geração, bem como as ferramentas de desenho de polígonos, aparecem na barra superior do Editor.
Para que a região funcione, um recurso NavigationPolygon precisa ser adicionado.
As propriedades para analisar e gerar uma malha de navegação fazem parte do recurso utilizado e podem ser encontradas no Inspetor do recurso.
O resultado da análise da geometria de origem pode ser influenciado pelas seguintes propriedades.
O
parsed_geometry_typeque filtra se objetos visuais, objetos de física ou ambos devem ser analisados a partir da SceneTree. Para mais detalhes sobre quais objetos são analisados e como, consulte a seção sobre análise de geometria de origem abaixo.O
collision_maskfiltra quais objetos de colisão de física são incluídos quando oparsed_geometry_typeinclui colisores estáticos (static colliders).O
source_geometry_modeque define em qual(is) nó(s) iniciar a análise e como percorrer a SceneTree.O
source_geometry_group_nameé usado quando apenas um determinado grupo de nós deve ser analisado. Depende dosource_geometry_modeselecionado.
Com a geometria de origem adicionada, o resultado do pré-cálculo(baking) pode ser controlado com as seguintes propriedades.
O
cell_sizedefine o tamanho da grade de rasterização e deve corresponder ao tamanho do mapa de navegação.O
agent_radiusencolhe a malha de navegação gerada para ter margem suficiente para o tamanho (de colisão) do agente.
A geração do NavigationRegion2D também pode ser usada em tempo de execução com scripts.
var on_thread: bool = true
bake_navigation_polygon(on_thread)
bool onThread = true;
BakeNavigationPolygon(onThread);
Para testar rapidamente a geração 2D com as configurações padrão:
Adicione um NavigationRegion2D.
Adicione um recurso NavigationPolygon ao NavigationRegion2D.
Adicione um Polygon2D abaixo do NavigationRegion2D.
Desenhe 1 contorno de NavigationPolygon com la ferramenta de desenho do NavigationRegion2D selecionada.
Desenhe 1 contorno de Polygon2D dentro do contorno do NavigationPolygon com a ferramenta de desenho do Polygon2D selecionada.
Pressione o botão de geração do Editor e uma malha de navegação deverá aparecer.
Quando um nó NavigationRegion3D é selecionado no Editor, as opções de geração aparecem na barra superior do Editor.
Para que a região funcione, um recurso NavigationMesh precisa ser adicionado.
As propriedades para analisar e gerar uma malha de navegação fazem parte do recurso utilizado e podem ser encontradas no Inspetor do recurso.
O resultado da análise da geometria de origem pode ser influenciado pelas seguintes propriedades.
O
parsed_geometry_typeque filtra se objetos visuais, objetos de física ou ambos devem ser analisados a partir da SceneTree. Para mais detalhes sobre quais objetos são analisados e como, consulte a seção sobre análise de geometria de origem abaixo.O
collision_maskfiltra quais objetos de colisão de física são incluídos quando oparsed_geometry_typeinclui colisores estáticos (static colliders).O
source_geometry_modeque define em qual(is) nó(s) iniciar a análise e como percorrer a SceneTree.O
source_geometry_group_nameé usado quando apenas um determinado grupo de nós deve ser analisado. Depende dosource_geometry_modeselecionado.
Com a geometria de origem adicionada, o resultado do pré-cálculo(baking) pode ser controlado com as seguintes propriedades.
O
cell_sizee ocell_heightdefinem o tamanho da grade de voxels de rasterização e devem corresponder ao tamanho do mapa de navegação.O
agent_radiusencolhe a malha de navegação gerada para ter margem suficiente para o tamanho (de colisão) do agente.O
agent_heightexclui áreas da malha de navegação onde o agente é alto demais para caber.O
agent_max_climbe oagent_max_sloperemovem áreas onde a diferença de altura entre voxels vizinhos é muito grande ou onde a superfície é muito íngreme.
Aviso
Um cell_size ou cell_height muito pequeno pode criar tantos voxels que tem o potencial de congelar o jogo ou até mesmo travá-lo (crash).
A geração do NavigationRegion3D também pode ser usada em tempo de execução com scripts.
var on_thread: bool = true
bake_navigation_mesh(on_thread)
bool onThread = true;
BakeNavigationMesh(onThread);
Para testar rapidamente a geração 3D com as configurações padrão:
Adicione um NavigationRegion3D.
Adicione um recurso NavigationMesh ao NavigationRegion3D.
Adicione um MeshInstance3D abaixo do NavigationRegion3D.
Adicione um PlaneMesh ao MeshInstance3D.
Pressione o botão de geração do Editor e uma malha de navegação deverá aparecer.
Assando uma malha de navegação com o NavigationServer
O NavigationServer2D e o NavigationServer3D possuem funções de API para chamar cada etapa do processo de geração de malha de navegação individualmente.
parse_source_geometry_data()pode ser usado para analisar a geometria de origem em um recurso reutilizável e serializável.bake_from_source_geometry_data()pode ser usado para gerar uma malha de navegação a partir de dados já analisados, por exemplo, para evitar problemas de desempenho em tempo de execução com análise (redundante).bake_from_source_geometry_data_async()é o mesmo, mas prepara a malha de navegação adiada com partes_paralelizáveis, não bloqueando a parte principal(main thread).
Comparado a uma NavigationRegion, o NavigationServer oferece um controle mais fino sobre o processo de geração de malha de navegação. Por sua vez, é mais complexo de usar, mas também fornece opções mais avançadas.
Algumas outras vantagens do NavigationServer em relação a uma NavigationRegion são:
O servidor pode analisar a geometria de origem sem gerar, por exemplo, para armazená-la em cache para uso posterior.
O servidor permite selecionar manualmente o nó raiz no qual iniciar a análise da geometria de origem.
O servidor pode aceitar e gerar a partir de dados de geometria de origem gerados proceduralmente.
O servidor pode gerar múltiplas malhas de navegação em sequência enquanto (re)utiliza os mesmos dados de geometria de origem.
Para gerar malhas de navegação com o NavigationServer, a geometria de origem é necessária. A geometria de origem é o conjunto de dados geométricos que deve ser considerado em um processo de geração de malha de navegação. Ambas as malhas de navegação para 2D e 3D são criadas gerando-as a partir da geometria de origem.
As versões 2D e 3D dos recursos de geometria de origem estão disponíveis como NavigationMeshSourceGeometryData2D e NavigationMeshSourceGeometryData3D, respectivamente.
A geometria de origem pode ser uma geometria analisada a partir de malhas visuais, de colisão de física ou matrizes de dados criadas proceduralmente, como contornos (2D) e faces de triângulos (3D). Por conveniência, a geometria de origem é comumente analisada diretamente a partir de configurações de nós na SceneTree. Para gerações (re-bakes) de malhas de navegação em tempo de execução, esteja ciente de que a análise geométrica sempre acontece na thread principal.
Nota
A SceneTree não é thread-safe. A análise da geometria de origem a partir da SceneTree só pode ser feita na thread principal.
Aviso
Os dados de malhas visuais e polígonos precisam ser recebidos da GPU, interrompendo (stalling) o RenderingServer no processo. Para a geração em tempo de execução, prefira usar formas de física como geometria de origem analisada.
A geometria de origem é armazenada dentro de recursos para que a geometria criada possa ser reutilizada para múltiplas gerações. Por exemplo, gerar múltiplas malhas de navegação para diferentes tamanhos de agentes a partir da mesma geometria de origem. Isso também permite salvar a geometria de origem no disco para que possa ser carregada mais tarde, por exemplo, para evitar o custo de processamento de analisá-la novamente em tempo de execução.
Os dados geométricos devem ser, em geral, mantidos muito simples. Tantas arestas quantas forem necessárias, mas o mínimo possível. Especialmente em 2D, geometrias duplicadas e aninhadas devem ser evitadas, pois forçam o cálculo de buracos em polígonos, o que pode resultar em polígonos invertidos. Um exemplo de geometria aninhada seria uma forma menor de StaticBody2D colocada completamente dentro dos limites de outra forma de StaticBody2D.
Assando pedaços de malha de navegação para mundos grandes
Construindo e atualizando blocos (chunks) individuais de malha de navegação em tempo de execução.
Ver também
Você pode ver o assamento de pedaços de malha de navegação em ação nos projetos de demonstração Navigation Mesh Chunks 2D e Navigation Mesh Chunks 3D.
Para evitar arestas desalinhadas entre diferentes blocos de região, as malhas de navegação possuem duas propriedades importantes para o processo de geração de malha de navegação: o limite de geração (baking bound) e o tamanho da borda (border size). Juntos, eles podem ser usados para garantir arestas perfeitamente alinhadas entre os blocos de região.
Bloco de malha de navegação gerado com limite de geração ou gerado com tamanho de borda adicional.
O limite de geração, que é um Rect2 alinhado aos eixos para 2D e um AABB para 3D, limita a geometria de origem usada descartando toda a geometria que estiver fora dos limites.
As propriedades de NavigationPolygon baking_rect e baking_rect_offset podem ser usadas para criar e posicionar o limite de geração 2D.
As propriedades de NavigationMesh filter_baking_aabb e filter_baking_aabb_offset podem ser usadas para criar e posicionar o limite de geração 3D.
Com apenas o limite de geração definido, outro problema ainda existe. A malha de navegação resultante será inevitavelmente afetada por deslocamentos necessários como o agent_radius, o que faz com que as arestas não se alinhem corretamente.
Blocos de malha de navegação com lacunas perceptíveis devido ao deslocamento do raio do agente gerado.
É aqui que entra a propriedade border_size para malhas de navegação. O tamanho da borda é uma margem interna a partir do limite de geração. A característica importante do tamanho da borda é que ele não é afetado pela maioria dos deslocamentos e pós-processamentos, como o agent_radius.
Em vez de descartar a geometria de origem, o tamanho da borda descarta partes da superfície final da malha de navegação gerada. Se o limite de geração for grande o suficiente, o tamanho da borda pode remover as partes problemáticas da superfície, de modo que reste apenas o tamanho pretendido do bloco.
Blocos de malha de navegação com arestas alinhadas e sem lacunas.
Nota
Os limites de geração precisam ser grandes o suficiente para incluir uma quantidade razoável de geometria de origem de todos os blocos vizinhos.
Aviso
Em 3D, a funcionalidade do tamanho da borda é limitada ao eixo xz.
Problemas comuns ao assar malha de navegação
Existem alguns problemas comuns dos usuários e ressalvas importantes a serem consideradas ao criar ou gerar malhas de navegação.
- O assamento da malha de navegação cria problemas de taxa de quadros em tempo de execução
O Pré-Calculo da Malha de navegação é feito por padrão em uma parte_paralelizável em segundo plano, portanto, desde que a plataforma suporte partes_paralelizáveis, o Pré-Calculo real raramente é a fonte de quaisquer problemas de desempenho (assumindo uma geometria complexa e de tamanho razoável para recálculo em tempo de execução).
A fonte comum para problemas de desempenho em tempo de execução é a etapa de análise da geometria de origem que envolve nós e a SceneTree. A SceneTree não é thread-safe, portanto todos os nós precisam ser analisados na thread principal. Alguns nós com muitos dados podem ser muito pesados e lentos para analisar em tempo de execução; por exemplo, um TileMap possui um ou mais polígonos para cada célula e TileMapLayer usada para analisar. Os nós que contêm malhas precisam solicitar os dados ao RenderingServer, interrompendo a renderização no processo.
Para melhorar o desempenho, use formas mais otimizadas, por exemplo, formas de colisão em vez de malhas visuais detalhadas, e mescle e simplifique o máximo de geometria possível de antemão. Se nada ajudar, não analise a SceneTree e adicione a geometria de origem de forma procedural com scripts. Se apenas matrizes de dados puros forem usadas como geometria de origem, todo o processo de geração poderá ser feito em uma thread de segundo plano.
- A malha de navegação cria buracos não intencionais em 2D.
A geração de malha de navegação em 2D é feita realizando operações de recorte de polígonos com base em caminhos de contorno. Polígonos com "buracos" são um mal necessário para criar polígonos 2D mais complexos, mas podem se tornar imprevisíveis para os usuários com muitas formas complexas envolvidas.
Para evitar problemas inesperados com cálculos de buracos em polígonos, evite aninhar quaisquer contornos dentro de outros contornos do mesmo tipo (atravessável / obstrução). Isso inclui as formas analisadas a partir dos nós. Por exemplo, colocar uma forma menor de StaticBody2D dentro de uma forma maior de StaticBody2D pode fazer com que o polígono resultante seja invertido.
- A malha de navegação aparece dentro da geometria em 3D.
A geração de malha de navegação em 3D não possui o conceito de "dentro". As células de voxel usadas para rasterizar a geometria estão ocupadas ou não. Remova a geometria que está no chão dentro da outra geometria. Se isso não for possível, adicione uma geometria "fictícia" (dummy) menor por dentro com o menor número possível de triângulos para que as células fiquem ocupadas com alguma coisa.
Uma forma de NavigationObstacle3D configurada para gerar com a malha de navegação também pode ser usada para descartar geometria.
Uma forma de NavigationObstacle3D pode ser usada para descartar partes indesejadas da malha de navegação.
Modelos de script de malha de navegação
O script a seguir usa o NavigationServer para analisar a geometria de origem a partir da árvore de cenas, gera uma malha de navegação e atualiza uma região de navegação com a malha de navegação atualizada.
extends Node2D
var navigation_mesh: NavigationPolygon
var source_geometry : NavigationMeshSourceGeometryData2D
var callback_parsing : Callable
var callback_baking : Callable
var region_rid: RID
func _ready() -> void:
navigation_mesh = NavigationPolygon.new()
navigation_mesh.agent_radius = 10.0
source_geometry = NavigationMeshSourceGeometryData2D.new()
callback_parsing = on_parsing_done
callback_baking = on_baking_done
region_rid = NavigationServer2D.region_create()
# Enable the region and set it to the default navigation map.
NavigationServer2D.region_set_enabled(region_rid, true)
NavigationServer2D.region_set_map(region_rid, get_world_2d().get_navigation_map())
# Some mega-nodes like TileMap are often not ready on the first frame.
# Also the parsing needs to happen on the main-thread.
# So do a deferred call to avoid common parsing issues.
parse_source_geometry.call_deferred()
func parse_source_geometry() -> void:
source_geometry.clear()
var root_node: Node2D = self
# Parse the obstruction outlines from all child nodes of the root node by default.
NavigationServer2D.parse_source_geometry_data(
navigation_mesh,
source_geometry,
root_node,
callback_parsing
)
func on_parsing_done() -> void:
# If we did not parse a TileMap with navigation mesh cells we may now only
# have obstruction outlines so add at least one traversable outline
# so the obstructions outlines have something to "cut" into.
source_geometry.add_traversable_outline(PackedVector2Array([
Vector2(0.0, 0.0),
Vector2(500.0, 0.0),
Vector2(500.0, 500.0),
Vector2(0.0, 500.0)
]))
# Bake the navigation mesh on a thread with the source geometry data.
NavigationServer2D.bake_from_source_geometry_data_async(
navigation_mesh,
source_geometry,
callback_baking
)
func on_baking_done() -> void:
# Update the region with the updated navigation mesh.
NavigationServer2D.region_set_navigation_polygon(region_rid, navigation_mesh)
using Godot;
public partial class MyNode2D : Node2D
{
private NavigationPolygon _navigationMesh;
private NavigationMeshSourceGeometryData2D _sourceGeometry;
private Callable _callbackParsing;
private Callable _callbackBaking;
private Rid _regionRid;
public override void _Ready()
{
_navigationMesh = new NavigationPolygon();
_navigationMesh.AgentRadius = 10.0f;
_sourceGeometry = new NavigationMeshSourceGeometryData2D();
_callbackParsing = Callable.From(OnParsingDone);
_callbackBaking = Callable.From(OnBakingDone);
_regionRid = NavigationServer2D.RegionCreate();
// Enable the region and set it to the default navigation map.
NavigationServer2D.RegionSetEnabled(_regionRid, true);
NavigationServer2D.RegionSetMap(_regionRid, GetWorld2D().NavigationMap);
// Some mega-nodes like TileMap are often not ready on the first frame.
// Also the parsing needs to happen on the main-thread.
// So do a deferred call to avoid common parsing issues.
CallDeferred(MethodName.ParseSourceGeometry);
}
private void ParseSourceGeometry()
{
_sourceGeometry.Clear();
Node2D rootNode = this;
// Parse the obstruction outlines from all child nodes of the root node by default.
NavigationServer2D.ParseSourceGeometryData(
_navigationMesh,
_sourceGeometry,
rootNode,
_callbackParsing
);
}
private void OnParsingDone()
{
// If we did not parse a TileMap with navigation mesh cells we may now only
// have obstruction outlines so add at least one traversable outline
// so the obstructions outlines have something to "cut" into.
_sourceGeometry.AddTraversableOutline(
[
new Vector2(0.0f, 0.0f),
new Vector2(500.0f, 0.0f),
new Vector2(500.0f, 500.0f),
new Vector2(0.0f, 500.0f),
]);
// Bake the navigation mesh on a thread with the source geometry data.
NavigationServer2D.BakeFromSourceGeometryDataAsync(_navigationMesh, _sourceGeometry, _callbackBaking);
}
private void OnBakingDone()
{
// Update the region with the updated navigation mesh.
NavigationServer2D.RegionSetNavigationPolygon(_regionRid, _navigationMesh);
}
}
extends Node3D
var navigation_mesh: NavigationMesh
var source_geometry : NavigationMeshSourceGeometryData3D
var callback_parsing : Callable
var callback_baking : Callable
var region_rid: RID
func _ready() -> void:
navigation_mesh = NavigationMesh.new()
navigation_mesh.agent_radius = 0.5
source_geometry = NavigationMeshSourceGeometryData3D.new()
callback_parsing = on_parsing_done
callback_baking = on_baking_done
region_rid = NavigationServer3D.region_create()
# Enable the region and set it to the default navigation map.
NavigationServer3D.region_set_enabled(region_rid, true)
NavigationServer3D.region_set_map(region_rid, get_world_3d().get_navigation_map())
# Some mega-nodes like GridMap are often not ready on the first frame.
# Also the parsing needs to happen on the main-thread.
# So do a deferred call to avoid common parsing issues.
parse_source_geometry.call_deferred()
func parse_source_geometry() -> void:
source_geometry.clear()
var root_node: Node3D = self
# Parse the geometry from all mesh child nodes of the root node by default.
NavigationServer3D.parse_source_geometry_data(
navigation_mesh,
source_geometry,
root_node,
callback_parsing
)
func on_parsing_done() -> void:
# Bake the navigation mesh on a thread with the source geometry data.
NavigationServer3D.bake_from_source_geometry_data_async(
navigation_mesh,
source_geometry,
callback_baking
)
func on_baking_done() -> void:
# Update the region with the updated navigation mesh.
NavigationServer3D.region_set_navigation_mesh(region_rid, navigation_mesh)
using Godot;
public partial class MyNode3D : Node3D
{
private NavigationMesh _navigationMesh;
private NavigationMeshSourceGeometryData3D _sourceGeometry;
private Callable _callbackParsing;
private Callable _callbackBaking;
private Rid _regionRid;
public override void _Ready()
{
_navigationMesh = new NavigationMesh();
_navigationMesh.AgentRadius = 0.5f;
_sourceGeometry = new NavigationMeshSourceGeometryData3D();
_callbackParsing = Callable.From(OnParsingDone);
_callbackBaking = Callable.From(OnBakingDone);
_regionRid = NavigationServer3D.RegionCreate();
// Enable the region and set it to the default navigation map.
NavigationServer3D.RegionSetEnabled(_regionRid, true);
NavigationServer3D.RegionSetMap(_regionRid, GetWorld3D().NavigationMap);
// Some mega-nodes like GridMap are often not ready on the first frame.
// Also the parsing needs to happen on the main-thread.
// So do a deferred call to avoid common parsing issues.
CallDeferred(MethodName.ParseSourceGeometry);
}
private void ParseSourceGeometry ()
{
_sourceGeometry.Clear();
Node3D rootNode = this;
// Parse the geometry from all mesh child nodes of the root node by default.
NavigationServer3D.ParseSourceGeometryData(
_navigationMesh,
_sourceGeometry,
rootNode,
_callbackParsing
);
}
private void OnParsingDone()
{
// Bake the navigation mesh on a thread with the source geometry data.
NavigationServer3D.BakeFromSourceGeometryDataAsync(_navigationMesh, _sourceGeometry, _callbackBaking);
}
private void OnBakingDone()
{
// Update the region with the updated navigation mesh.
NavigationServer3D.RegionSetNavigationMesh(_regionRid, _navigationMesh);
}
}
O script a seguir usa o NavigationServer para atualizar uma região de navegação com dados de malha de navegação gerados proceduralmente.
extends Node2D
var navigation_mesh: NavigationPolygon
var region_rid: RID
func _ready() -> void:
navigation_mesh = NavigationPolygon.new()
region_rid = NavigationServer2D.region_create()
# Enable the region and set it to the default navigation map.
NavigationServer2D.region_set_enabled(region_rid, true)
NavigationServer2D.region_set_map(region_rid, get_world_2d().get_navigation_map())
# Add vertices for a convex polygon.
navigation_mesh.vertices = PackedVector2Array([
Vector2(0.0, 0.0),
Vector2(100.0, 0.0),
Vector2(100.0, 100.0),
Vector2(0.0, 100.0),
])
# Add indices for the polygon.
navigation_mesh.add_polygon(
PackedInt32Array([0, 1, 2, 3])
)
NavigationServer2D.region_set_navigation_polygon(region_rid, navigation_mesh)
using Godot;
public partial class MyNode2D : Node2D
{
private NavigationPolygon _navigationMesh;
private Rid _regionRid;
public override void _Ready()
{
_navigationMesh = new NavigationPolygon();
_regionRid = NavigationServer2D.RegionCreate();
// Enable the region and set it to the default navigation map.
NavigationServer2D.RegionSetEnabled(_regionRid, true);
NavigationServer2D.RegionSetMap(_regionRid, GetWorld2D().NavigationMap);
// Add vertices for a convex polygon.
_navigationMesh.Vertices =
[
new Vector2(0, 0),
new Vector2(100.0f, 0),
new Vector2(100.0f, 100.0f),
new Vector2(0, 100.0f),
];
// Add indices for the polygon.
_navigationMesh.AddPolygon([0, 1, 2, 3]);
NavigationServer2D.RegionSetNavigationPolygon(_regionRid, _navigationMesh);
}
}
extends Node3D
var navigation_mesh: NavigationMesh
var region_rid: RID
func _ready() -> void:
navigation_mesh = NavigationMesh.new()
region_rid = NavigationServer3D.region_create()
# Enable the region and set it to the default navigation map.
NavigationServer3D.region_set_enabled(region_rid, true)
NavigationServer3D.region_set_map(region_rid, get_world_3d().get_navigation_map())
# Add vertices for a convex polygon.
navigation_mesh.vertices = PackedVector3Array([
Vector3(-1.0, 0.0, 1.0),
Vector3(1.0, 0.0, 1.0),
Vector3(1.0, 0.0, -1.0),
Vector3(-1.0, 0.0, -1.0),
])
# Add indices for the polygon.
navigation_mesh.add_polygon(
PackedInt32Array([0, 1, 2, 3])
)
NavigationServer3D.region_set_navigation_mesh(region_rid, navigation_mesh)
using Godot;
public partial class MyNode3D : Node3D
{
private NavigationMesh _navigationMesh;
private Rid _regionRid;
public override void _Ready()
{
_navigationMesh = new NavigationMesh();
_regionRid = NavigationServer3D.RegionCreate();
// Enable the region and set it to the default navigation map.
NavigationServer3D.RegionSetEnabled(_regionRid, true);
NavigationServer3D.RegionSetMap(_regionRid, GetWorld3D().NavigationMap);
// Add vertices for a convex polygon.
_navigationMesh.Vertices =
[
new Vector3(-1.0f, 0.0f, 1.0f),
new Vector3(1.0f, 0.0f, 1.0f),
new Vector3(1.0f, 0.0f, -1.0f),
new Vector3(-1.0f, 0.0f, -1.0f),
];
// Add indices for the polygon.
_navigationMesh.AddPolygon([0, 1, 2, 3]);
NavigationServer3D.RegionSetNavigationMesh(_regionRid, _navigationMesh);
}
}