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.

Utilizzare gli NavigationPathQueryObject

Suggerimento

I parametri di query del percorso offrono diverse opzioni per migliorare le prestazioni di ricerca del percorso o ridurre il consumo della memoria.

Sono progettati per esigenze più avanzate di ricerca del percorso, che i nodi di alto livello non riescono sempre a coprire.

Consulta le rispettive sezioni delle opzioni di seguito.

I NavigationPathQueryObject si possono utilizzare insieme a NavigationServer.query_path() per ottenere un percorso di navigazione notevolmente personalizzato, inclusi metadati facoltativi relativi al percorso.

Questo richiede una configurazione più complessa rispetto a ottenere un normale NavigationPath, ma consente di personalizzare la ricerca del percorso e i dati del percorso forniti, in base alle diverse esigenze di un progetto.

I NavigationPathQueryObject sono costituiti da una coppia di oggetti: un oggetto NavigationPathQueryParameters che contiene le opzioni di personalizzazione per la query e un oggetto NavigationPathQueryResult che riceve aggiornamenti (regolari) con il percorso risultante e i metadati dalla query.

Le versioni 2D e 3D di NavigationPathQueryParameters sono disponibili rispettivamente come NavigationPathQueryParameters2D e NavigationPathQueryParameters3D.

Le versioni 2D e 3D di NavigationPathQueryResult sono disponibili rispettivamente come NavigationPathQueryResult2D e NavigationPathQueryResult3D.

Creating a basic path query

Both parameters and result are used as a pair with the NavigationServer.query_path() function.

For the available customization options, see further below. See also the descriptions for each parameter in the class reference.

While not a strict requirement, both objects are intended to be created once in advance, stored in a persistent variable for the agent and reused for every followup path query with updated parameters.

Riutilizzare gli stessi oggetti migliora le prestazioni quando si creano oggetti o si alloca memoria frequentemente.

Lo script seguente crea gli oggetti e fornisce una funzione query_path() per creare nuovi percorsi di navigazione. Il percorso risultante è identico a quello ottenuto tramite NavigationServer.map_get_path(), riutilizzando al contempo gli oggetti.

extends Node2D

# Prepare query objects.
var query_parameters := NavigationPathQueryParameters2D.new()
var query_result := NavigationPathQueryResult2D.new()

func query_path(p_start_position: Vector2, p_target_position: Vector2, p_navigation_layers: int = 1) -> PackedVector2Array:
    if not is_inside_tree():
        return PackedVector2Array()

    var map: RID = get_world_2d().get_navigation_map()

    if NavigationServer2D.map_get_iteration_id(map) == 0:
        # This map has never synced and is empty, no point in querying it.
        return PackedVector2Array()

    query_parameters.map = map
    query_parameters.start_position = p_start_position
    query_parameters.target_position = p_target_position
    query_parameters.navigation_layers = p_navigation_layers

    NavigationServer2D.query_path(query_parameters, query_result)
    var path: PackedVector2Array = query_result.get_path()

    return path

Path postprocessing options

Differenze nella post-elaborazione del percorso a seconda della disposizione dei poligoni della mesh di navigazione

Differenze nella post-elaborazione del percorso a seconda della disposizione dei poligoni della mesh di navigazione.

Una ricerca di percorso si sposta dal bordo del poligono della mesh di navigazione più vicino al bordo più vicino lungo i poligoni disponibili. Se possibile, costruisce un corridoio poligonale verso il poligono della posizione di destinazione.

Questo percorso poligonale grezzo "di ricerca" non è molto ottimizzato e solitamente non adatto al movimento degli agenti. Ad esempio, il punto di bordo più vicino su un poligono di navigazione potrebbe causare una deviazione enorme per gli agenti su poligoni più grandi. Per migliorare la qualità dei percorsi restituiti dalla richiesta, esistono diverse opzioni path_postprocessing.

  • La post-elaborazione PATH_POSTPROCESSING_CORRIDORFUNNEL accorcia i percorsi incanalandoli attorno agli angoli dentro il corridoio poligonale disponibile.

    Questa è la post-elaborazione predefinita e solitamente anche la più utile, poiché fornisce il percorso più breve dentro il corridoio poligonale disponibile. Se il corridoio poligonale è già subottimale, ad esempio a causa di una disposizione subottimale della mesh di navigazione, l'imbuto può agganciarsi ad angoli poligonali imprevisti, causando deviazioni.

  • La post-elaborazione PATH_POSTPROCESSING_EDGECENTERED impone che tutti i punti del percorso siano posizionati al centro dei bordi del poligono incrociato dentro il corridoio poligonale disponibile.

    Questa post-elaborazione è generalmente utile solo se utilizzata con poligoni di navigazione strettamente simili a tessere, tutti di dimensioni uniformi, e dove il percorso previsto è vincolato ai centri delle celle, ad esempio nei tipici giochi a griglia con movimento limitato ai centri delle celle.

  • La post-elaborazione PATH_POSTPROCESSING_NONE restituisce il percorso così come è stato percorso dalla ricerca dentro il corridoio poligonale disponibile.

    Questa post-elaborazione è molto utile per il debug, in quanto mostra come la ricerca del percorso si è spostata dal punto di bordo più vicino al punto di bordo più vicino e quali poligoni ha scelto. È possibile immediatamente giustificare molti risultati di percorsi inattesi o non ottimali esaminando questo percorso grezzo e il corridoio poligonale.

Path simplification

Suggerimento

La semplificazione del percorso può aiutare a sterzare gli agenti o agenti che vibrano sui bordi sottili dei poligoni.

Differenza dei punti del percorso con o senza semplificazione del percorso

Differenza dei punti del percorso con o senza semplificazione del percorso.

Se simplify_path è abilitato, al percorso è applicata una variante dell'algoritmo di semplificazione del percorso Ramer-Douglas-Peucker. Questo algoritmo raddrizza i percorsi rimuovendo i punti meno rilevanti a seconda del valore di simplify_epsilon utilizzato.

La semplificazione del percorso aiuta a risolvere tanti tipi di problemi di movimento degli agenti in "campi aperti", causati dalla presenza di molti bordi poligonali superflui. Ad esempio, una mesh del terreno, quando viene preparata in una mesh di navigazione, può generare un numero eccessivo di poligoni a causa di tutte le piccole variazioni di altezza nel terreno (che, ai fini della ricerca del percorso, sono quasi irrilevanti).

Path simplification also helps with "steering" agents because they only have more critical corner path points to aim for.

Avvertimento

La semplificazione del percorso è un'ulteriore post-elaborazione finale del percorso. Ha un impatto in più sulle prestazioni della ricerca, quindi abilitala solo quando è effettivamente necessaria.

Nota

La semplificazione del percorso è esposta sul NavigationServer come funzione generica. Può essere utilizzata anche al di fuori delle ricerche di navigazione per tutti i tipi di array di posizioni.

Path metadata

Suggerimento

Disabling unneeded path metadata options can improve performance and lower memory consumption.

A path query can return additional metadata for every path point.

  • Il flag PATH_METADATA_INCLUDE_TYPES raccoglie un array con le informazioni delle primitive sui proprietari dei punti, ad esempio se un punto appartiene a una regione o a un collegamento.

  • Il flag PATH_METADATA_INCLUDE_RIDS raccoglie un array con i RID dei proprietari dei punti. A seconda delle primitive del proprietario del punto, questi RID si possono usare con le varie funzioni del NavigationServer relative a regioni o collegamenti.

  • Il flag PATH_METADATA_INCLUDE_OWNERS raccoglie un array con gli ObjectID dei proprietari dei punti. Questi ID oggetto si possono usare con @GlobalScope.instance_from_id() per recuperare il nodo dietro quell'istanza di oggetto, ad esempio un nodo NavigationRegion o NavigationLink.

Per valore predefinito, vengono raccolti tutti i metadati di percorso, poiché possono essere essenziali per un gameplay di navigazione più avanzato.

  • Ad esempio, per sapere quale punto del percorso è mappato a quale oggetto o proprietario di un nodo all'interno dello SceneTree.

  • E.g. to know if a path point is the start or end of a navigation link that requires scripted takeover.

Per gli utilizzi più basilari dei percorsi, i metadati non sono sempre necessari. La raccolta dei metadati del percorso si può disabilitare selettivamente per migliorare le prestazioni e ridurre il consumo di memoria.

Escludere o includere regioni

Suggerimento

I filtri di regioni possono migliorare notevolmente le prestazioni su mappe grandi di navigazione suddivise per regione.

I parametri di richiesta consentono di limitare la ricerca del percorso a specifiche mesh di navigazione di regione.

Se una mappa grande di navigazione è suddivisa in regioni più piccole, ciò può migliorare notevolmente le prestazioni, poiché la richiesta può saltare un gran numero di poligoni in una delle prime verifiche nella ricerca del percorso.

  • Normalmente e se lasciati vuoti, sono incluse tutte le regioni della mappa interrogata di navigazione.

  • Se il RID di una regione è aggiunto all'array excluded_regions, la mesh di navigazione della regione sarà ignorata nella ricerca del percorso.

  • Se il RID di una regione è aggiunto all'array included_regions, la mesh di navigazione della regione sarà considerata nella ricerca del percorso e tutte le altre regioni non incluse saranno ignorate.

  • Se una regione risulta sia inclusa sia esclusa, è considerata esclusa.

I filtri di regione sono molto efficaci per le prestazioni se abbinati a blocchi di navigazione allineati su una griglia. In questo modo, il filtro può essere impostato per includere solo il blocco della posizione iniziale e i blocchi circostanti, anziché l'intera mappa di navigazione.

Anche se la destinazione potrebbe trovarsi fuori da questi blocchi circostanti (è sempre possibile aggiungere altri "anelli"), l'algoritmo di ricerca cercherà di creare un percorso verso il poligono più vicino alla destinazione. Questo solitamente crea dei percorsi parziali che si dirigono nella direzione generale e che risultano abbastanza buoni, il tutto con un impatto sulle prestazioni nettamente inferiore rispetto a una ricerca completa sulla mappa.

The following addition to the basic path query script showcases the idea how to integrate a region chunk mapping with the region filters. This is not a full working example.

extends Node2D

# ...

var chunk_id_to_region_rid: Dictionary[Vector2i, RID] = {}

func query_path(p_start_position: Vector2, p_target_position: Vector2, p_navigation_layers: int = 1) -> PackedVector2Array:

    # ...

    var regions_around_start_position: Array[RID] = []

    var chunk_rings: int = 1 # Increase for very small regions or more quality.
    var start_chunk_id: Vector2i = floor(p_start_position / float(chunk_size))

    for y: int in range(start_chunk_id.y - chunk_rings, start_chunk_id.y + chunk_rings):
        for x: int in range(start_chunk_id.x - chunk_rings, start_chunk_id.x + chunk_rings):
            var chunk_id: Vector2i = Vector2i(x, y)
            if chunk_id_to_region_rid.has(chunk_id):
                var region: RID = chunk_id_to_region_rid[chunk_id]
                regions_around_start_position.push_back(region)

    query_parameters.included_regions = regions_around_start_position

    # ...

Troncamento e limiti del percorso

Suggerimento

Impostare limiti ragionevoli può migliorare notevolmente le prestazioni su mappe grandi di navigazione, soprattutto quando le destinazioni risultano irraggiungibili.

Troncare i percorsi restituiti a distanze specifiche

Troncare i percorsi restituiti a distanze specifiche.

I parametri di richiesta consentono di troncare i percorsi restituiti a lunghezze specifiche. Queste opzioni troncano il percorso durante la fase di post-elaborazione. Il percorso è comunque cercato come se fosse nella sua lunghezza completa, quindi manterrà la stessa qualità. Il troncamento della lunghezza del percorso può essere utile per creare percorsi più adatti a dinamiche di gioco vincolate, ad esempio nei giochi tattici con portata limitata di movimento.

  • La proprietà path_return_max_length serve per troncare il percorso restituito a una lunghezza massima specifica.

  • La proprietà path_return_max_radius serve per troncare il percorso restituito all'interno di un cerchio (2D) o di una sfera (3D) attorno al raggio della posizione di partenza.

I parametri di richiesta consentono di limitare la ricerca del percorso a una distanza specifica o a un numero specifico di poligoni da esaminare. Queste opzioni sono pensate per migliorare le prestazioni e influiscono direttamente sulla ricerca del percorso.

  • La proprietà path_search_max_distance serve per interrompere la ricerca del percorso quando si supera questa distanza dalla posizione di partenza.

  • La proprietà path_search_max_polygons serve per interrompere la ricerca del percorso quando si supera questo numero di poligoni cercati.

Quando la ricerca del percorso è interrotta per raggiungimento di un limite, il percorso viene ripristinato e viene creato un percorso dal poligono di partenza al poligono trovato finora che è più vicino alla posizione di destinazione.

Avvertimento

Sebbene sia buono per le prestazioni, se i valori limite per la ricerca del percorso sono impostati troppo bassi, possono influire molto negativamente sulla qualità del percorso stesso. A seconda della disposzioni dei poligoni e dello schema di ricerca, i percorsi restituiti potrebbero andare in direzioni completamente errate anziché nella direzione di destinazione.