Up to date
This page is up to date for Godot 4.2
.
If you still find outdated information, please open an issue.
Übersicht 2D-Navigation¶
Godot bietet eine Vielzahl von Objekten, Klassen und Servern, die eine raster- oder meshbasierte Navigation und Wegfindung für 2D- und 3D-Spiele ermöglichen. Der folgende Abschnitt gibt einen schnellen Überblick über alle in Godot verfügbaren Navigationsobjekte für 2D-Szenen und ihre primäre Verwendung.
Godot bietet die folgenden Objekte und Klassen für die 2D-Navigation:
- Astar2D
Die
Astar2D
-Objekte bieten die Möglichkeit, den kürzesten Weg in einem Graphen aus gewichteten Punkten zu finden.Die Klasse AStar2D eignet sich am besten für zellbasierte 2D-Spiele, bei denen die Akteure nicht jede mögliche Position innerhalb eines Bereichs erreichen müssen, sondern nur vordefinierte, eindeutige Positionen.
- NavigationServer2D
Der
NavigationServer2D
stellt eine leistungsfähige Server-API zur Verfügung, um den kürzesten Weg zwischen zwei Positionen auf einer durch ein Navigations-Mesh definierten Fläche zu finden.Der NavigationServer eignet sich am besten für 2D-Echtzeitspiele, bei denen die Akteure jede mögliche Position innerhalb eines durch ein Mesh definierten Navigationsbereichs 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 viele, viele Rasterzellen benötigt würden.
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
Referenz auf einen bestimmten Ausweichagenten. Die Art des Ausweichens wird durch einen Radiuswert angegeben.
- 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 NavigationServer2D-API verfügbar.
- NavigationRegion2D-Node
Ein Node, der eine NavigationPolygon-Ressource enthält, die ein Navigations-Mesh für den NavigationServer2D definiert.
Die Region kann aktiviert / deaktiviert werden.
Die Verwendung in der Wegfindung kann durch die Bitmaske
navigation_layers
weiter eingeschränkt werden.Der NavigationServer2D fügt die Navigations-Meshes der Regionen nach ihrer Nähe zu einem kombinierten Mesh zusammen.
- NavigationLink2D-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.
- NavigationAgent2D-Node
Ein Helfer-Node, der allgemeine NavigationServer2D-API-Aufrufe für Wegfindung und -vermeidung erleichtert. Verwenden Sie diesen Node mit einem Parent-Node, der von Node2D abgeleitet ist.
- NavigationObstacle2D-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 2D-Navigationsmeshes werden mit den folgenden Ressourcen definiert:
- NavigationPolygon-Ressource
Eine Ressource, die 2D-Navigations-Mesh-Daten enthält. Sie bietet Tools zum Zeichnen von Polygonen, um die Definition von Navigationsbereichen sowohl im Editor als auch zur Laufzeit zu ermöglichen.
Der NavigationRegion2D-Node verwendet diese Ressource, um seinen Navigationsbereich zu definieren.
Der NavigationServer2D verwendet diese Ressource, um das Navigations-Mesh einzelner Regionen zu aktualisieren.
Der TileSet-Editor erstellt und verwendet diese Ressource intern, wenn er Tile-Navigationsbereiche definiert.
Siehe auch
Wie die 2D-Navigation in Aktion funktioniert, können Sie anhand der Demoprojekte 2D-Navigationspolygon und Rasterbasierte Navigation mit AStarGrid2D sehen.
Einrichtung für 2D-Szenen¶
Die folgenden Schritte zeigen den grundlegenden Aufbau einer minimal funktionsfähigen Navigation in 2D. Es verwendet den NavigationServer2D und einen NavigationAgent2D für die Pfadbewegung.
Fügen Sie einen NavigationRegion2D-Node zur Szene hinzu.
Klicken Sie auf den Regions-Node und fügen Sie eine neue NavigationPolygon-Resource zum Regions-Node hinzu.
Definieren Sie den beweglichen Navigationsbereich mit dem Zeichenwerkzeug von NavigationPolygon.
Bemerkung
Das Navigations-Mesh definiert den Bereich, in dem ein Akteur stehen und sich mit seinem Zentrum bewegen kann. Lassen Sie genügend Spielraum zwischen den Kanten des Navigationspolygons und den Kollisionsobjekten, damit Akteure, die einem Pfad folgen, nicht wiederholt an Kollisionen hängen bleiben.
Fügen Sie einen CharacterBody2D-Node in der Szene mit einer einfachen Kollisions-Shape und einem Sprite oder Mesh für die visuelle Darstellung hinzu.
Fügen Sie einen NavigationAgent2D-Node unterhalb des Charakter-Nodes hinzu.
Fügen Sie das folgende Skript zum CharacterBody2D-Node hinzu. Wir stellen sicher, dass wir ein Bewegungsziel festlegen, nachdem die Szene vollständig geladen wurde und der NavigationServer Zeit hatte, sich zu synchronisieren.
extends CharacterBody2D
var movement_speed: float = 200.0
var movement_target_position: Vector2 = Vector2(60.0,180.0)
@onready var navigation_agent: NavigationAgent2D = $NavigationAgent2D
func _ready():
# These values need to be adjusted for the actor's speed
# and the navigation layout.
navigation_agent.path_desired_distance = 4.0
navigation_agent.target_desired_distance = 4.0
# 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: Vector2):
navigation_agent.target_position = movement_target
func _physics_process(delta):
if navigation_agent.is_navigation_finished():
return
var current_agent_position: Vector2 = global_position
var next_path_position: Vector2 = navigation_agent.get_next_path_position()
velocity = current_agent_position.direction_to(next_path_position) * movement_speed
move_and_slide()
using Godot;
public partial class MyCharacterBody2D : CharacterBody2D
{
private NavigationAgent2D _navigationAgent;
private float _movementSpeed = 200.0f;
private Vector2 _movementTargetPosition = new Vector2(70.0f, 226.0f);
public Vector2 MovementTarget
{
get { return _navigationAgent.TargetPosition; }
set { _navigationAgent.TargetPosition = value; }
}
public override void _Ready()
{
base._Ready();
_navigationAgent = GetNode<NavigationAgent2D>("NavigationAgent2D");
// These values need to be adjusted for the actor's speed
// and the navigation layout.
_navigationAgent.PathDesiredDistance = 4.0f;
_navigationAgent.TargetDesiredDistance = 4.0f;
// Make sure to not await during _Ready.
Callable.From(ActorSetup).CallDeferred();
}
public override void _PhysicsProcess(double delta)
{
base._PhysicsProcess(delta);
if (_navigationAgent.IsNavigationFinished())
{
return;
}
Vector2 currentAgentPosition = GlobalTransform.Origin;
Vector2 nextPathPosition = _navigationAgent.GetNextPathPosition();
Velocity = currentAgentPosition.DirectionTo(nextPathPosition) * _movementSpeed;
MoveAndSlide();
}
private async void ActorSetup()
{
// Wait for the first physics frame so the NavigationServer can sync.
await ToSignal(GetTree(), SceneTree.SignalName.PhysicsFrame);
// Now that the navigation map is no longer empty, set the movement target.
MovementTarget = _movementTargetPosition;
}
}
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.