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...
Utilizzo di mesh di navigazione
Le versioni 2D e 3D della mesh di navigazione sono disponibili rispettivamente come NavigationPolygon e NavigationMesh.
Nota
Una mesh di navigazione descrive soltanto un'area percorribile per la posizione centrale di un agente. Qualsiasi valore di raggio che un agente possa avere è ignorato. Se vuoi che la ricerca del percorso tenga conto delle dimensioni (e delle collisioni) di un agente, bisogna rimpicciolire adeguatamente la mesh di navigazione.
La navigazione funziona indipendentemente dalle altre parti del motore, come il rendering o la fisica. Le mesh di navigazione sono le uniche cose considerate durante la ricerca del percorso; ad esempio, gli elementi visivi e le forme di collisione sono completamente ignorati dal sistema di navigazione. Se vuoi tenere conto di altri dati (come ad esempio gli elementi visivi) durante la ricerca del percorso, bisogna adattare adeguatamente le mesh di navigazione. La procedura per tenere conto delle restrizioni nelle mesh di navigazione è comunemente detto "navigation mesh baking".
Una mesh di navigazione descrive una superficie su cui un agente può posizionarsi in sicurezza, con il suo centro confrontato con le forme fisiche che descrivono i limiti esterni di collisione.
Se riscontri problemi di clipping o collisione mentre si seguono i percorsi di navigazione, ricorda sempre che devi dire cosa vuoi fare al sistema di navigazione tramite un'apposita mesh di navigazione. Il sistema di navigazione, di per sé, non saprà mai "questa è una forma o una mesh visiva di collisione per alberi/rocce/muri" perché sa solo che "qui mi è stato detto che posso percorrere il percorso in sicurezza perché si trova su una mesh di navigazione".
La preparazione delle mesh di navigazione si può effettuare attraverso un NavigationRegion2D o un NavigationRegion3D, oppure direttamente attraverso le API del NavigationServer2D e del NavigationServer3D.
Preparazione di una mesh di navigazione con una NavigationRegion
Baking a navigation mesh with agent radius offset from geometry.
La preparazione delle mesh di navigazione è reso più accessibile grazie al nodo NavigationRegion. Quando si utilizza un nodo NavigationRegion per la preparazione, le singole fasi di analisi, preparazione e aggiornamento della regione vengono combinate in un'unica funzione.
I nodi sono disponibili in 2D e 3D come NavigationRegion2D e NavigationRegion3D rispettivamente.
Suggerimento
La mesh di navigazione source_geometry_mode può essere configurata per analizzare nomi di gruppi di nodi specifici, così che i nodi da preparare si possano collocare ovunque nella scena.
Quando si seleziona un nodo NavigationRegion2D nell'Editor, le opzioni di preparazione e gli strumenti di disegno dei poligoni appaiono nella barra superiore dell'Editor.
Affinché la regione funzioni, è necessario aggiungere una risorsa NavigationPolygon.
Le proprietà necessarie per analizzare e preparare una mesh di navigazione fanno quindi parte della risorsa utilizzata e si possono trovare nell'Ispettore della risorsa.
Il risultato dell'analisi della geometria sorgente può essere influenzato dalle seguenti proprietà.
parsed_geometry_typefiltra se si devono analizzare oggetti visivi, oggetti fisici o entrambi dallo SceneTree. Per maggiori dettagli su quali oggetti sono analizzati e in che modo, consulta la sezione sull'analisi della geometria sorgente riportata di seguito.collision_maskfiltra quali oggetti di collisione fisica sono inclusi quandoparsed_geometry_typeinclude collisori statici.source_geometry_modeche definisce da quali nodi iniziare l'analisi e come attraversare lo SceneTree.source_geometry_group_nameserve quando si desidera analizzare solo un certo gruppo di nodi. Dipende dalla modalitàsource_geometry_modeselezionata.
Aggiunta la geometria della sorgente, il risultato della preparazione può essere controllato con le seguenti proprietà.
cell_sizedefinisce la dimensione della griglia di rasterizzazione e dovrebbe corrispondere alla dimensione della mappa di navigazione.agent_radiusrimpicciolisce la mesh di navigazione precalcolata per avere un margine sufficiente per le dimensioni dell'agente (collisione).
La preparazione di NavigationRegion2D si può effettuare anche in fase di esecuzione tramite script.
var on_thread: bool = true
bake_navigation_polygon(on_thread)
bool onThread = true;
BakeNavigationPolygon(onThread);
Per testare rapidamente il precalcolo 2D con le impostazioni predefinite:
Aggiungi un NavigationRegion2D.
Aggiungi una risorsa NavigationPolygon al NavigationRegion2D.
Aggiungi un Polygon2D sotto il NavigationRegion2D.
Disegna il 1 contorno NavigationPolygon con lo strumento di disegno NavigationRegion2D selezionato.
Disegna il 1 contorno Polygon2D dentro il contorno NavigationPolygon con lo strumento di disegno Polygon2D selezionato.
Clicca sul pulsante di preparazione nell'editor e dovrebbe apparire una mesh di navigazione.
Quando un nodo NavigationRegion3D è selezionato nell'editor, le opzioni di preparazione sono visualizzate nella barra superiore dell'editor.
Affinché la regione funzioni, è necessario aggiungere una risorsa NavigationMesh.
Le proprietà necessarie per analizzare e preparare una mesh di navigazione fanno quindi parte della risorsa utilizzata e si possono trovare nell'Ispettore della risorsa.
Il risultato dell'analisi della geometria sorgente può essere influenzato dalle seguenti proprietà.
parsed_geometry_typefiltra se si devono analizzare oggetti visivi, oggetti fisici o entrambi dallo SceneTree. Per maggiori dettagli su quali oggetti sono analizzati e in che modo, consulta la sezione sull'analisi della geometria sorgente riportata di seguito.collision_maskfiltra quali oggetti di collisione fisica sono inclusi quandoparsed_geometry_typeinclude collisori statici.source_geometry_modeche definisce da quali nodi iniziare l'analisi e come attraversare lo SceneTree.source_geometry_group_nameserve quando si desidera analizzare solo un certo gruppo di nodi. Dipende dalla modalitàsource_geometry_modeselezionata.
Aggiunta la geometria della sorgente, il risultato della preparazione può essere controllato con le seguenti proprietà.
cell_sizeecell_heightdefiniscono le dimensioni della griglia di voxel per la rasterizzazione e dovrebbero corrispondere alle dimensioni della mappa di navigazione.agent_radiusrimpicciolisce la mesh di navigazione precalcolata per avere un margine sufficiente per le dimensioni dell'agente (collisione).agent_heightesclude dalla mesh di navigazione le aree in cui l'agente è troppo alto per passarvi.agent_max_climbeagent_max_sloperimuovono le aree in cui la differenza di altezza tra i voxel adiacenti è eccessiva, o in cui la loro superficie è troppo ripida.
Avvertimento
Un valore di cell_size o cell_height troppo piccolo può creare così tanti voxel da rischiare di bloccare il gioco o addirittura causare un crash.
La preparazione di NavigationRegion3D si può usare anche in fase di esecuzione tramite script.
var on_thread: bool = true
bake_navigation_mesh(on_thread)
bool onThread = true;
BakeNavigationMesh(onThread);
Per testare rapidamente la preparazione 3D con le impostazioni predefinite:
Aggiungi un NavigationRegion3D.
Aggiungi una risorsa NavigationMesh al NavigationRegion3D.
Aggiungi un MeshInstance3D sotto il NavigationRegion3D.
Aggiungi un PlaneMesh al MeshInstance3D.
Clicca sul pulsante di preparazione nell'editor e dovrebbe apparire una mesh di navigazione.
Preparazione una mesh di navigazione con il NavigationServer
NavigationServer2D e NavigationServer3D includono funzioni per richiamare singolarmente ogni fase del processo di preparazione per le mesh di navigazione.
parse_source_geometry_data()può servire per analizzare la geometria sorgente e convertirla in una risorsa riutilizzabile e serializzabile.bake_from_source_geometry_data()può servire per generare una mesh di navigazione partendo da dati già analizzati, ad esempio per evitare problemi di prestazioni dovuti ad analisi (ridondanti) durante l'esecuzione.bake_from_source_geometry_data_async()è lo stesso ma prepara la mesh di navigazione in modo differito con altri thread, senza bloccare il thread principale.
Rispetto a un NavigationRegion, il NavigationServer offre un controllo più preciso sul processo di preparazione della mesh di navigazione. Di conseguenza, è più complicato da usare, ma offre anche opzioni più avanzate.
Alcuni altri vantaggi del NavigationServer rispetto a un NavigationRegion sono:
Il server può analizzare la geometria sorgente senza doverla precalcolare, ad esempio per memorizzarla e usarla in futuro.
Il server consente di selezionare il nodo radice da cui avviare l'analisi manuale della geometria sorgente.
Il server è in grado di accettare e preparare i dati di geometria sorgente generata proceduralmente.
Il server è in grado di preparare in sequenza più mesh di navigazione, (ri)utilizzando gli stessi dati di geometria sorgente.
Per preparare le mesh di navigazione con il NavigationServer, è necessaria la geometria sorgente. La geometria sorgente è un'insieme di dati da considerare nel processo di precalcolo delle mesh di navigazione. Sia le mesh di navigazione 2D sia quelle 3D vengono create preparandole dalla geometria sorgente.
Le versioni 2D e 3D delle risorse di geometria sorgente sono disponibili rispettivamente come NavigationMeshSourceGeometryData2D e NavigationMeshSourceGeometryData3D.
La geometria sorgente si può ricavare da mesh visive, da collisioni fisiche o da array di dati creati proceduralmente, come contorni (2D) e facce triangolari (3D). Per comodità, la geometria sorgente viene comunemente ricavata direttamente dalle configurazioni dei nodi nell'albero di scene. Per il (ri)calcolo delle mesh di navigazione in fase di esecuzione, tieni presente che il prelievo della geometria avviene sempre sul thread principale.
Nota
Lo SceneTree non è thread-safe. L'analisi della geometria sorgente dallo SceneTree si può eseguire solo sul thread principale.
Avvertimento
I dati provenienti da mesh e poligoni visivi devono essere ricevuti dalla GPU, di conseguenza bloccando il RenderingServer. Per la (ri)preparazione in fase di esecuzione, è preferibile utilizzare forme fisiche come geometria sorgente analizzata.
La geometria sorgente è memorizzata all'interno delle risorse, così che la geometria creata si possa riutilizzare per più preparazioni. Ad esempio, per preparare più mesh di navigazione per diverse dimensioni di agenti partendo dalla stessa geometria sorgente. Ciò consente anche di salvare la geometria sorgente su disco, così da poterla caricare in seguito, ad esempio per evitare l'impatto di doverla rianalizzare in fase di esecuzione.
In generale, i dati geometrici si dovrebbero mantenere molto semplici. Tanti bordi quanti sono necessari, ma il minor numero possibile. Soprattutto in 2D, è opportuno evitare geometrie duplicate e annidate, poiché ciò comporta il calcolo di fori poligonali che possono far ribaltare i poligoni. Un esempio di geometria annidata potrebbe essere una forma StaticBody2D più piccola collocata completamente entro i limiti di un'altra forma StaticBody2D.
Preparare blocchi di mesh di navigazione per grandi mondi
Creazione e aggiornamento dei singoli blocchi della mesh di navigazione in fase di esecuzione.
Vedi anche
È possibile osservare la preparazione dei blocchi di mesh di navigazione in azione nei progetti demo Navigation Mesh Chunks 2D e Navigation Mesh Chunks 3D.
Per evitare disallineamenti dei bordi tra le diversi chunk di regione, le mesh di navigazione includono due proprietà importanti per il processo di preparazione: il limite di preparazione e la dimensione di bordo. Insieme servono a garantire un allineamento perfetto dei bordi tra i chunk di regione.
Chunk di mesh di navigazione, preparato con limite di preparazione o con una dimensione di bordo in più.
Il confine di preparazione, che è un Rect2 allineato agli assi per il 2D e un AABB per il 3D, limita la geometria sorgente utilizzata, scartando tutta la geometria che si trova fuori dai limiti.
Le proprietà baking_rect e baking_rect_offset del NavigationPolygon si possono usare per creare e posizionare il confine di preparazione 2D.
Le proprietà filter_baking_aabb e filter_baking_aabb_offset del NavigationMesh si possono usare per creare e posizionare il confine di preparazione 3D.
Anche impostando solo il confine di preparazione, esiste ancora un altro problema. La mesh di navigazione risultante sarà inevitabilmente influenzata da offset necessari come agent_radius, che non fanno allineare correttamente i bordi.
Navigation mesh chunks with noticeable gaps due to baked agent radius offset.
È qui che entra in gioco la proprietà border_size per la mesh di navigazione. La dimensione del bordo è un margine interno rispetto al confine di preparazione. La caratteristica importante della dimensione del bordo è che non è influenzata dalla maggior parte degli offset e delle post-elaborazioni, come agent_radius.
Anziché scartare la geometria sorgente, la dimensione di bordo scarta parti della superficie finale della mesh di navigazione preparata. Se il limite di preparazione è grande abbastanza, la dimensione di bordo può rimuovere le parti problematiche della superficie, così che rimanga solo la dimensione del chunk desiderato.
Chunk di mesh di navigazione con bordi allineati e senza distacchi.
Nota
The baking bounds need to be large enough to include a reasonable amount of source geometry from all the neighboring chunks.
Avvertimento
In 3D la funzionalità della dimensione di bordo è limitata all'asse xz.
Problemi comuni preparando le mesh di navigazione
Esistono alcuni problemi comuni riscontrati dagli utenti e importanti avvertenze da considerare quando si creano o si generano mesh di navigazione.
- La preparazione delle mesh di navigazione crea problemi di frame rate in fase di esecuzione
La preparazione della mesh di navigazione è eseguita normalmente su un thread in background, quindi, fin quando la piattaforma supporti i thread, la preparazione vera e propria raramente è la causa di problemi di prestazioni (supponendo una geometria di dimensioni e complessità ragionevoli per nuove preparazioni in fase di esecuzione).
La causa più comune dei problemi di prestazioni in fase di esecuzione è la fase di analisi della geometria sorgente, che coinvolge i nodi e lo SceneTree. Lo SceneTree non è thread-safe, quindi tutti i nodi si devono analizzare sul thread principale. Alcuni nodi con molti dati possono essere molto pesanti e lenti da analizzare in fase di esecuzione. Ad esempio, una TileMap ha uno o più poligoni per ogni singola cella utilizzata e TileMapLayer da analizzare. I nodi che contengono mesh devono richiedere dati dal RenderingServer, bloccando il rendering nel processo.
Per migliorare le prestazioni, utilizza forme più ottimizzate, ad esempio forme di collisione al posto di mesh visive dettagliate, e unisci e semplifica quanta più geometria possibile in anticipo. Se nulla aiuta, non analizzare lo SceneTree e aggiungi la geometria sorgente proceduralmente con script. Se come geometria sorgente sono utilizzati solo array di dati puri, l'intero processo di preparazione può essere eseguito su un thread in background.
- La mesh di navigazione crea fori indesiderati in 2D.
La preparazione della mesh di navigazione in 2D avviene tramite operazioni di ritaglio dei poligoni basate su percorsi di contorno. I poligoni con "buchi" sono un male necessario per creare poligoni 2D più complessi, ma possono risultare imprevedibili per gli utenti che utilizzano molte forme complesse.
Per evitare problemi imprevisti con i calcoli dei fori nei poligoni, è bene evitare di annidare contorni all'interno di altri contorni dello stesso tipo (percorribili/ostacoli). Questo vale anche per le forme estratte dai nodi. Ad esempio, inserire una forma StaticBody2D più piccola all'interno di una forma StaticBody2D più grande potrebbe capovolgere il poligono risultante.
- Mesh di navigazione appare dentro la geometria in 3D.
La preparazione della mesh di navigazione in 3D non ha un concetto di "interno". Le celle voxel utilizzate per rasterizzare la geometria sono o occupate o vuote. Rimuovi la geometria che sta sul terreno all'interno dell'altra geometria. Se ciò non è possibile, aggiungi una geometria "fittizia" più piccola all'interno, con il minor numero possibile di triangoli, affinché le celle siano occupate da qualcosa.
Una forma NavigationObstacle3D impostata per la preparazione con una mesh di navigazione può anche essere utilizzata per scartare la geometria.
È possibile utilizzare una forma NavigationObstacle3D per scartare le parti indesiderate di una mesh di navigazione.
Modelli di script per le mesh di navigazione
Lo script seguente utilizza il NavigationServer per analizzare la geometria sorgente dall'albero di scene, prepara una mesh di navigazione e aggiorna una regione di navigazione con la mesh di navigazione aggiornata.
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);
}
}
Lo script seguente utilizza il NavigationServer per aggiornare una regione di navigazione con dati di mesh di navigazione generati 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);
}
}