Up to date

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

Verwenden von NavigationObstacles

NavigationObstacles können entweder als statische oder dynamische Hindernisse verwendet werden, um ausweichgesteuerte Agenten zu beeinflussen.

  • Bei statischer Verwendung von NavigationObstacles werden ausweichgesteuerte Agenten außerhalb oder innerhalb eines durch ein Polygon definierten Bereichs eingeschränkt.

  • Wenn sie dynamisch eingesetzt werden, stoßen Navigationshindernisse die ausweichgesteuerten Agenten in einem Radius um sie herum weg.

2D- und 3D-Versionen von NavigationObstacle-Nodes sind als NavigationObstacle2D bzw. NavigationObstacle3D verfügbar.

Bemerkung

NavigationObstacles verändern oder beeinflussen die Wegfindung in keiner Weise. Navigationshindernisse wirken sich nur auf die Ausweichgeschwindigkeiten von ausweichgesteuerten Agenten aus.

Statische Hindernisse

Ein NavigationObstacle wird als statisch angesehen, wenn seine vertices-Property mit einem Array von Positionen gefüllt ist, um ein Polygon zu bilden.

../../_images/nav_static_obstacle_build.gif
  • Statische Hindernisse fungieren als harte nicht zu überquerende Grenzen für die Vermeidung durch Agenten, z.B. ähnlich wie physikalische Kollisionen, aber für das Ausweichen.

  • Statische Hindernisse definieren ihre Grenzen mit einem Array von Vertices (Positionen), und im Falle von 3D mit einer zusätzlichen Höhe-Property.

  • Statische Hindernisse funktionieren nur bei Agenten, die den 2D-Ausweichmodus verwenden.

  • Statische Hindernisse definieren sich durch die Wicklungsrichtung der Vertices, wenn Agenten herausgeschoben oder hineingesaugt werden.

  • Statische Hindernisse können ihre Position nicht verändern. Sie können nur an eine neue Position gesetzt und von Grund auf neu aufgebaut werden. Statische Hindernisse sind daher für Anwendungen, bei denen die Position in jedem Frame geändert wird, schlecht geeignet, da der ständige Neuaufbau mit hohen Performance-Kosten verbunden ist.

  • Statische Hindernisse, die an eine andere Position gesetzt werden, können von den Agenten nicht vorhergesagt werden. Dadurch besteht die Gefahr, dass die Agenten stecken bleiben, wenn ein statisches Hindernis über den Agenten gesetzt wird.

Wenn das 2D-Ausweichen in 3D verwendet wird, wird die y-Achse der Vector3-Vertices ignoriert. Stattdessen wird die globale y-Achsen-Position des Hindernisses als Höhenebene verwendet. Agenten ignorieren statische Hindernisse in 3D, die sich unter oder über ihnen befinden. Dies wird automatisch durch die globale y-Achsenposition des Hindernisses und des Agenten als Höhenebene sowie durch ihre jeweiligen Höheneigenschaften bestimmt.

Dynamische Objekte

Ein NavigationObstacle wird als dynamisch angesehen, wenn seine Property Radius größer als Null ist.

  • Dynamische Hindernisse fungieren als weiches "Bitte-weg-von-mir"-Objekt, dem Agenten ausweichen, z.B. ähnlich wie sie anderen Agenten ausweichen.

  • Dynamische Hindernisse definieren ihre Grenzen mit einem einzigen Radius für einen 2D-Kreis, oder im Falle der 3D-Umgehung einer Kugel.

  • Dynamische Hindernisse können ihre Position bei jedem Bild ohne zusätzliche Performance-Kosten ändern.

  • Dynamische Hindernisse mit einer bestimmten Geschwindigkeit können in ihrer Bewegung von Agenten vorhergesagt werden.

  • Dynamische Hindernisse sind kein zuverlässiges Mittel, um Agenten in überfüllten oder engen Räumen einzuschränken.

Obwohl sowohl statische als auch dynamische Propertys gleichzeitig für ein und dasselbe Hindernis aktiv sein können, ist dies aus Performance-Gründen nicht empfehlenswert. Wenn sich ein Hindernis bewegt, werden idealerweise die statischen Vertices entfernt und stattdessen der Radius aktiviert. Wenn das Hindernis die neue Endposition erreicht, sollte es seinen Radius allmählich vergrößern, um alle anderen Agenten wegzuschieben. Wenn genug Platz um das Hindernis herum geschaffen wurde, sollte es die statischen Vertices wieder hinzufügen und den Radius entfernen. Dies hilft zu vermeiden, dass Agenten in dem plötzlich auftauchenden statischen Hindernis stecken bleiben, wenn der Wiederaufbau der statischen Begrenzung abgeschlossen ist.

Ähnlich wie die Agenten können die Hindernisse die Bitmaske avoidance_layers verwenden. Alle Agenten mit einem passenden Bit auf ihrer eigenen Ausweichmaske werden das Hindernis meiden.

Prozedurale Hindernisse

Neue Hindernisse können ohne einen Node direkt auf dem NavigationServer erstellt werden.

Hindernisse, die mit Skripten erstellt werden, benötigen mindestens eine Map und eine Position. Für die dynamische Verwendung wird ein Radius benötigt. Für die statische Verwendung wird ein Array von Vertices benötigt.

# For 2D

# create a new "obstacle" and place it on the default navigation map.
var new_obstacle_rid: RID = NavigationServer2D.obstacle_create()
var default_2d_map_rid: RID = get_world_2d().get_navigation_map()

NavigationServer2D.obstacle_set_map(new_obstacle_rid, default_2d_map_rid)
NavigationServer2D.obstacle_set_position(new_obstacle_rid, global_position)

# Use obstacle dynamic by increasing radius above zero.
NavigationServer2D.obstacle_set_radius(new_obstacle_rid, 5.0)

# Use obstacle static by adding a square that pushes agents out.
var outline = PackedVector2Array([Vector2(-100, -100), Vector2(100, -100), Vector2(100, 100), Vector2(-100, 100)])
NavigationServer2D.obstacle_set_vertices(new_obstacle_rid, outline)

# Enable the obstacle.
NavigationServer2D.obstacle_set_avoidance_enabled(new_obstacle_rid, true)
# For 3D

# Create a new "obstacle" and place it on the default navigation map.
var new_obstacle_rid: RID = NavigationServer3D.obstacle_create()
var default_3d_map_rid: RID = get_world_3d().get_navigation_map()

NavigationServer3D.obstacle_set_map(new_obstacle_rid, default_3d_map_rid)
NavigationServer3D.obstacle_set_position(new_obstacle_rid, global_position)

# Use obstacle dynamic by increasing radius above zero.
NavigationServer3D.obstacle_set_radius(new_obstacle_rid, 0.5)

# Use obstacle static by adding a square that pushes agents out.
var outline = PackedVector3Array([Vector3(-5, 0, -5), Vector3(5, 0, -5), Vector3(5, 0, 5), Vector3(-5, 0, 5)])
NavigationServer3D.obstacle_set_vertices(new_obstacle_rid, outline)
# Set the obstacle height on the y-axis.
NavigationServer3D.obstacle_set_height(new_obstacle_rid, 1.0)

# Enable the obstacle.
NavigationServer3D.obstacle_set_avoidance_enabled(new_obstacle_rid, true)