Up to date

This page is up to date for Godot 4.2. If you still find outdated information, please open an issue.

Übersicht 3D-Navigation

Godot bietet eine Vielzahl von Objekten, Klassen und Servern, die eine raster- oder mesh-basierte Navigation und Wegfindung für 2D- und 3D-Spiele ermöglichen. Der folgende Abschnitt bietet einen schnellen Überblick über alle in Godot für 3D-Szenen verfügbaren navigationsbezogenen Objekte und ihre primäre Verwendung.

Godot bietet die folgenden Objekte und Klassen für die 3D-Navigation:

  • Astar3D

    Astar3D-Objekte bieten die Möglichkeit, den kürzesten Weg in einem Graphen aus gewichteten Punkten zu finden.

    Die Klasse AStar3D eignet sich am besten für zellbasierte 3D-Spiele, bei denen die Akteure nicht jede mögliche Position innerhalb eines Bereichs erreichen müssen, sondern nur vordefinierte, eindeutige Positionen.

  • NavigationServer3D

    Der NavigationServer3D bietet eine leistungsfähige Server-API, um den kürzesten Weg zwischen zwei Positionen auf einem durch ein Navigations-Mesh definierten Gebiet zu finden.

    Der NavigationServer eignet sich am besten für 3D-Echtzeitspiele, bei denen die Akteure jede mögliche Position innerhalb eines durch ein Navigations-Mesh definierten Bereichs erreichen müssen. Mesh-basierte Navigation skaliert gut mit großen Spielwelten, da ein großer Bereich oft mit einem einzigen Polygon definiert werden kann, während dafür sehr viele Rasterzellen erforderlich wären.

    Der NavigationServer enthält verschiedene Navigations-Maps, die jeweils aus Regionen mit Navigations-Mesh-Daten bestehen. Agenten können zur Ausweichberechnung auf einer Map platziert werden. RIDs werden verwendet, um bei der Kommunikation mit dem Server auf interne Maps, Regionen und Agenten zu verweisen.

    Die folgenden NavigationServer-RID-Typen sind verfügbar.
    • NavMap-RID

      Referenz auf eine bestimmte Navigations-Map, die Regionen und Agenten enthält. Die Map versucht, die Navigations-Meshes der Regionen nach Entfernung zueinander zu verbinden. Die Map synchronisiert Regionen und Agenten in jedem Physik-Frame.

    • NavRegion-RID

      Referenz auf eine bestimmte Navigationsregion, die Navigations-Mesh-Daten enthalten kann. Die Region kann mit einer Navigations-Ebenen-Bitmaske aktiviert / deaktiviert oder ihre Verwendung eingeschränkt werden.

    • NavLink-RID

      Referenz auf eine bestimmte Navigationsverknüpfung, die zwei Mesh-Positionen über beliebige Entfernungen miteinander verbindet.

    • NavAgent-RID

      Verweis auf einen bestimmten Ausweichagenten. Das Ausweichverhalten wird durch einen Radiuswert definiert.

    • NavObstacle-RID

      Referenz auf ein bestimmtes Ausweichhindernis, um die Ausweichgeschwindigkeit der Agenten zu beeinflussen und einzuschränken.

Die folgenden Nodes des Szenenbaums sind als Hilfsmittel für die Arbeit mit der NavigationServer3D API verfügbar.

  • NavigationRegion3D-Node

    Ein Node, der eine Navigation Mesh-Ressource enthält, die ein Navigations-Mesh für den NavigationServer3D definiert.

    • Die Region kann aktiviert / deaktiviert werden.

    • Die Verwendung in der Wegfindung kann durch die Bitmaske navigation_layers weiter eingeschränkt werden.

    • Der NavigationServer3D verbindet die Navigations-Meshes der Regionen nach ihrer Nähe zu einem kombinierten Navigations-Mesh.

  • NavigationLink3D-Node

    Ein Node, der zwei Positionen auf Navigations-Meshes über beliebige Entfernungen zur Wegfindung verbindet.

    • Die Verknüpfung kann aktiviert/deaktiviert werden.

    • Die Verknüpfung kann in eine Richtung oder in beide Richtungen erfolgen.

    • Die Verwendung in der Wegfindung kann durch die Bitmaske navigation_layers weiter eingeschränkt werden.

    Verknüpfungen teilen der Wegfindung mit, dass eine Verbindung besteht und mit welchen Kosten. Die eigentliche Agentenbehandlung und -bewegung muss in benutzerdefinierten Skripten erfolgen.

  • NavigationAgent3D-Node

    Ein Helfer-Node, der verwendet wird, um allgemeine NavigationServer3D API-Aufrufe für Pfadfindung und -ausweichen zu erleichtern. Verwenden Sie diesen Node mit einem Parent-Node der von Node3D erbt.

  • NavigationObstacle3D-Node

    Ein Node, der verwendet werden kann, um die Ausweichgeschwindigkeit von ausweichfähigen Agenten zu beeinflussen und einzuschränken. Dieser Node hat KEINEN Einfluss auf die Wegfindung von Agenten. Sie müssen stattdessen die Navigations-Meshes für diese ändern.

Die 3D-Navigationsmeshes werden mit den folgenden Ressourcen definiert:

  • NavigationMesh-Ressource

    Eine Ressource, die 3D-Navigations-Mesh-Daten enthält. Sie bietet Optionen zum Backen von 3D-Geometrie, um Navigationsbereiche sowohl im Editor als auch zur Laufzeit zu definieren.

    • Der NavigationRegion3D-Node verwendet diese Ressource, um seinen Navigationsbereich zu definieren.

    • Der NavigationServer3D verwendet diese Ressource, um das Navigations-Mesh einzelner Regionen zu aktualisieren.

    • Der GridMap-Editor verwendet diese Ressource, wenn für jede Rasterzelle spezifische Meshes für die Navigation definiert werden.

Siehe auch

Sie können sehen, wie die 3D-Navigation in Aktion funktioniert, indem Sie das 3D Navigation-Demoprojekt verwenden.

Einrichtung für 3D-Szenen

Die folgenden Schritte zeigen einen grundlegenden Aufbau für eine minimal funktionsfähige Navigation in 3D. Es verwendet den NavigationServer3D und einen NavigationAgent3D für die Pfadbewegung.

  1. Fügen Sie einen NavigationRegion3D-Node zur Szene hinzu.

  2. Klicken Sie auf den Regions-Node und fügen Sie eine neue NavigationMesh-Ressource zu dem Regions-Node hinzu.

    ../../_images/nav_3d_min_setup_step1.png
  3. Fügen Sie einen neuen MeshInstance3D-Node als Child des Regions-Nodes hinzu.

  4. Wählen Sie den Node MeshInstance3D, fügen Sie ein neues PlaneMesh hinzu und erhöhen Sie die xy-Größe auf 10.

  5. Wählen Sie den Node der Region erneut aus und drücken Sie die Schaltfläche "Navmesh backen" in der oberen Leiste.

    ../../_images/nav_3d_min_setup_step2.png
  6. Jetzt erscheint ein transparentes Navigations-Mesh, das in einiger Entfernung über dem PlaneMesh schwebt.

    ../../_images/nav_3d_min_setup_step3.png
  7. Fügen Sie einen CharacterBody3D-Node in der Szene mit einer einfachen Collision Shape und einem Mesh zur Visualisierung hinzu.

  8. Fügen Sie einen NavigationAgent3D-Node unterhalb des Charakter-Nodes hinzu.

    ../../_images/nav_3d_min_setup_step4.webp
  9. Fügen Sie dem CharacterBody3D-Node ein Skript mit dem folgenden Inhalt hinzu. Wir stellen sicher, dass wir ein Bewegungsziel setzen, nachdem die Szene vollständig geladen wurde und der NavigationServer Zeit hatte, sich zu synchronisieren. Füge auch eine Camera3D und etwas Licht und Umgebung hinzu, um etwas zu sehen.

extends CharacterBody3D

var movement_speed: float = 2.0
var movement_target_position: Vector3 = Vector3(-3.0,0.0,2.0)

@onready var navigation_agent: NavigationAgent3D = $NavigationAgent3D

func _ready():
    # These values need to be adjusted for the actor's speed
    # and the navigation layout.
    navigation_agent.path_desired_distance = 0.5
    navigation_agent.target_desired_distance = 0.5

    # Make sure to not await during _ready.
    call_deferred("actor_setup")

func actor_setup():
    # Wait for the first physics frame so the NavigationServer can sync.
    await get_tree().physics_frame

    # Now that the navigation map is no longer empty, set the movement target.
    set_movement_target(movement_target_position)

func set_movement_target(movement_target: Vector3):
    navigation_agent.set_target_position(movement_target)

func _physics_process(delta):
    if navigation_agent.is_navigation_finished():
        return

    var current_agent_position: Vector3 = global_position
    var next_path_position: Vector3 = navigation_agent.get_next_path_position()

    velocity = current_agent_position.direction_to(next_path_position) * movement_speed
    move_and_slide()

Bemerkung

Beim ersten Frame hat die NavigationServer-Map die Regionsdaten noch nicht synchronisiert und jede Pfadabfrage liefert "leer" zurück. Warten Sie auf die NavigationServer-Synchronisierung, indem Sie im Skript ein Frame abwarten.