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.

Utilizzo dei NavigationPath

Ottenere un NavigationPath

I percorsi di navigazione si possono interrogare direttamente dal NavigationServer e non richiedono nodi o oggetti aggiuntivi, a condizione che la mappa di navigazione abbia una mesh di navigazione con cui lavorare.

Per ottenere un percorso 2D, usa NavigationServer2D.map_get_path(map, from, to, optimize, navigation_layers).

Per ottenere un percorso 3D, usa NavigationServer3D.map_get_path(map, from, to, optimize, navigation_layers).

For more customizable navigation path queries that require additional setup see Utilizzare gli NavigationPathQueryObject.

Uno dei parametri richiesti per la richiesta è il RID della mappa di navigazione. Ogni mondo di gioco ha una mappa di navigazione predefinita creata automaticamente. È possibile recuperare le mappe di navigazione predefinite tramite get_world_2d().get_navigation_map() da qualsiasi nodo che eredita da Node2D o tramite get_world_3d().get_navigation_map() da qualsiasi nodo che eredita da Node3D. Il secondo e il terzo parametro sono la posizione di partenza e la posizione di destinazione come Vector2 per il 2D o Vector3 per il 3D.

Se il parametro optimized è impostato su true, le posizioni del percorso saranno accorciate lungo gli angoli dei poligoni con un ulteriore passaggio dell'algoritmo a imbuto. Questo funziona bene per il movimento libero sulle mesh di navigazione con poligoni di dimensioni diverse, poiché il percorso si avvicinerà agli angoli lungo il corridoio poligonale trovato dall'algoritmo A*. Con celle piccole, l'algoritmo A* crea un corridoio a imbuto molto stretto che può generare percorsi d'angolo sgradevoli se utilizzato con le griglie.

Se il parametro optimized è impostato su false, le posizioni di percorso saranno collocate al centro di ciascun lato del poligono. Questo funziona bene per il movimento su griglia pura nelle mesh di navigazione con poligoni di dimensioni uguali, poiché il percorso passerà attraverso il centro delle celle della griglia. Al di fuori delle griglie, poiché i poligoni spesso coprono ampie aree aperte con un singolo lato lungo, questo può creare percorsi con deviazioni eccessivamente lunghe.

extends Node2D

# Basic query for a navigation path using the default navigation map.

func get_navigation_path(p_start_position: Vector2, p_target_position: Vector2) -> PackedVector2Array:
    if not is_inside_tree():
        return PackedVector2Array()

    var default_map_rid: RID = get_world_2d().get_navigation_map()
    var path: PackedVector2Array = NavigationServer2D.map_get_path(
        default_map_rid,
        p_start_position,
        p_target_position,
        true
    )
    return path

Un percorso (path) restituito dal NavigationServer sarà un PackedVector2Array per il 2D o un PackedVector3Array per il 3D. È semplicemente un Array ottimizzato per la memoria, contenente posizioni sotto forma di vettori. Tutti i vettori di posizione all'interno dell'array sono garantiti essere dentro un NavigationPolygon o un NavigationMesh. L'array del percorso, se non vuoto, contiene la posizione della mesh di navigazione più vicina alla posizione di partenza all'indice path[0]. La posizione della mesh di navigazione più vicina alla posizione di destinazione è l'ultima posizione all'indice path[path.size()-1]. Tutti gli indici intermedi sono i punti del percorso che un attore dovrebbe seguire per raggiungere la destinazione senza uscire dalla mesh di navigazione.

Nota

Se la posizione di destinazione si trova su una mesh di navigazione diversa, non unita o connessa, il percorso di navigazione porterà alla posizione più vicina possibile sulla mesh di navigazione della posizione di partenza.

Il seguente script muove un nodo che eredita da Node3D lungo un percorso di navigazione utilizzando la mappa di navigazione predefinita, impostando la posizione di destinazione con set_movement_target().

@onready var default_3d_map_rid: RID = get_world_3d().get_navigation_map()

var movement_speed: float = 4.0
var movement_delta: float
var path_point_margin: float = 0.5

var current_path_index: int = 0
var current_path_point: Vector3
var current_path: PackedVector3Array

func set_movement_target(target_position: Vector3):

    var start_position: Vector3 = global_transform.origin

    current_path = NavigationServer3D.map_get_path(
        default_3d_map_rid,
        start_position,
        target_position,
        true
    )

    if not current_path.is_empty():
        current_path_index = 0
        current_path_point = current_path[0]

func _physics_process(delta):

    if current_path.is_empty():
        return

    movement_delta = movement_speed * delta

    if global_transform.origin.distance_to(current_path_point) <= path_point_margin:
        current_path_index += 1
        if current_path_index >= current_path.size():
            current_path = []
            current_path_index = 0
            current_path_point = global_transform.origin
            return

    current_path_point = current_path[current_path_index]

    var new_velocity: Vector3 = global_transform.origin.direction_to(current_path_point) * movement_delta

    global_transform.origin = global_transform.origin.move_toward(global_transform.origin + new_velocity, movement_delta)