Update some navigation code examples

Updates some navigation code examples.
This commit is contained in:
smix8
2024-02-15 21:49:42 +01:00
parent ec3e094bf9
commit cac53e5d15
6 changed files with 146 additions and 82 deletions
@@ -44,20 +44,23 @@ The default 3D ``edge_connection_margin`` can be changed in the ProjectSettings
The edge connection margin value of any navigation map can also be changed at runtime with the NavigationServer API.
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 2D GDScript
extends Node2D
# 2D margins are designed to work with "pixel" values
var default_2d_map_rid: RID = get_world_2d().get_navigation_map()
NavigationServer2D.map_set_edge_connection_margin(default_2d_map_rid, 50.0)
.. tabs::
.. code-tab:: gdscript GDScript
func _ready() -> void:
# 2D margins are designed to work with 2D "pixel" values.
var default_map_rid: RID = get_world_2d().get_navigation_map()
NavigationServer2D.map_set_edge_connection_margin(default_map_rid, 50.0)
.. code-tab:: gdscript 3D GDScript
extends Node3D
# 3D margins are designed to work with 3D unit values
var default_3d_map_rid: RID = get_world_3d().get_navigation_map()
NavigationServer3D.map_set_edge_connection_margin(default_3d_map_rid, 0.5)
func _ready() -> void:
# 3D margins are designed to work with 3D world unit values.
var default_map_rid: RID = get_world_3d().get_navigation_map()
NavigationServer3D.map_set_edge_connection_margin(default_map_rid, 0.5)
.. note::
@@ -23,7 +23,40 @@ without the need for more complex bitwise operations.
In scripts the following helper functions can be used to work with the ``navigation_layers`` bitmask.
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 2D GDScript
func change_layers():
var region: NavigationRegion2D = get_node("NavigationRegion2D")
# enables 4-th layer for this region
region.navigation_layers = enable_bitmask_inx(region.navigation_layers, 4)
# disables 1-rst layer for this region
region.navigation_layers = disable_bitmask_inx(region.navigation_layers, 1)
var agent: NavigationAgent2D = get_node("NavigationAgent2D")
# make future path queries of this agent ignore regions with 4-th layer
agent.navigation_layers = disable_bitmask_inx(agent.navigation_layers, 4)
var path_query_navigation_layers: int = 0
path_query_navigation_layers = enable_bitmask_inx(path_query_navigation_layers, 2)
# get a path that only considers 2-nd layer regions
var path: PoolVector2Array = NavigationServer2D.map_get_path(
map,
start_position,
target_position,
true,
path_query_navigation_layers
)
static func is_bitmask_inx_enabled(_bitmask: int, _index: int) -> bool:
return _bitmask & (1 << _index) != 0
static func enable_bitmask_inx(_bitmask: int, _index: int) -> int:
return _bitmask | (1 << _index)
static func disable_bitmask_inx(_bitmask: int, _index: int) -> int:
return _bitmask & ~(1 << _index)
.. code-tab:: gdscript 3D GDScript
func change_layers():
var region: NavigationRegion3D = get_node("NavigationRegion3D")
@@ -26,18 +26,19 @@ The 2D default navigation map RID can be obtained with ``get_world_2d().get_navi
The 3D default navigation map RID can be obtained with ``get_world_3d().get_navigation_map()`` from any :ref:`Node3D<class_Node3D>` inheriting Node.
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 2D GDScript
extends Node2D
var default_2d_navigation_map_rid: RID = get_world_2d().get_navigation_map()
func _ready() -> void:
var default_navigation_map_rid: RID = get_world_2d().get_navigation_map()
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 3D GDScript
extends Node3D
var default_3d_navigation_map_rid: RID = get_world_3d().get_navigation_map()
func _ready() -> void:
var default_navigation_map_rid: RID = get_world_3d().get_navigation_map()
Creating new navigation maps
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -57,20 +58,21 @@ Navigation regions and avoidance agents can only be part of a single navigation
A navigation map switch will take effect only after the next NavigationServer synchronization.
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 2D GDScript
extends Node2D
var new_navigation_map: RID = NavigationServer2D.map_create()
NavigationServer2D.map_set_active(true)
func _ready() -> void:
var new_navigation_map: RID = NavigationServer2D.map_create()
NavigationServer2D.map_set_active(true)
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 3D GDScript
extends Node3D
var new_navigation_map: RID = NavigationServer3D.map_create()
NavigationServer3D.map_set_active(true)
func _ready() -> void:
var new_navigation_map: RID = NavigationServer3D.map_create()
NavigationServer3D.map_set_active(true)
.. note::
@@ -30,33 +30,43 @@ This reuse avoids performance implications from frequent object creation if a pr
has a large quantity of simultaneous agents that regularly update their paths.
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 2D GDScript
# prepare query objects
var query_parameters = NavigationPathQueryParameters2D.new()
var query_result = NavigationPathQueryResult2D.new()
# Prepare query objects.
var query_parameters := NavigationPathQueryParameters2D.new()
var query_result := NavigationPathQueryResult2D.new()
# update parameters object
query_parameters.map = get_world_2d().get_navigation_map()
query_parameters.start_position = agent2d_current_global_position
query_parameters.target_position = agent2d_target_global_position
func query_path(p_start_position: Vector2, p_target_position: Vector2, p_navigation_layers: int = 1) -> PackedVector2Array:
if not is_inside_tree():
return PackedVector2Array()
# update result object
NavigationServer2D.query_path(query_parameters, query_result)
var path: PackedVector2Array = query_result.get_path()
query_parameters.map = get_world_2d().get_navigation_map()
query_parameters.start_position = p_start_position
query_parameters.target_position = p_target_position
query_parameters.navigation_layers = p_navigation_layers
.. tabs::
.. code-tab:: gdscript GDScript
NavigationServer2D.query_path(query_parameters, query_result)
var path: PackedVector2Array = query_result.get_path()
# prepare query objects
var query_parameters = NavigationPathQueryParameters3D.new()
var query_result = NavigationPathQueryResult3D.new()
return path
# update parameters object
query_parameters.map = get_world_3d().get_navigation_map()
query_parameters.start_position = agent3d_current_global_position
query_parameters.target_position = agent3d_target_global_position
# update result object
NavigationServer3D.query_path(query_parameters, query_result)
var path: PackedVector3Array = query_result.get_path()
.. code-tab:: gdscript 3D GDScript
# Prepare query objects.
var query_parameters := NavigationPathQueryParameters3D.new()
var query_result := NavigationPathQueryResult3D.new()
func query_path(p_start_position: Vector3, p_target_position: Vector3, p_navigation_layers: int = 1) -> PackedVector3Array:
if not is_inside_tree():
return PackedVector3Array()
query_parameters.map = get_world_3d().get_navigation_map()
query_parameters.start_position = p_start_position
query_parameters.target_position = p_target_position
query_parameters.navigation_layers = p_navigation_layers
NavigationServer3D.query_path(query_parameters, query_result)
var path: PackedVector3Array = query_result.get_path()
return path
@@ -33,34 +33,43 @@ Outside of grids due to polygons often covering large open areas with a single,
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 2D GDScript
extends Node2D
# basic query for a navigation path in 2D using the default navigation map
var default_2d_map_rid: RID = get_world_2d().get_navigation_map()
var start_position: Vector2 = Vector2(0.0, 0.0)
var target_position: Vector2 = Vector2(5.0, 0.0)
var path: PackedVector2Array = NavigationServer2D.map_get_path(
default_2d_map_rid,
start_position,
target_position,
true
)
.. tabs::
.. code-tab:: gdscript GDScript
# 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
.. code-tab:: gdscript 3D GDScript
extends Node3D
# basic query for a navigation path in 3D using the default navigation map
var default_3d_map_rid: RID = get_world_3d().get_navigation_map()
var start_position: Vector3 = Vector3(0.0, 0.0, 0.0)
var target_position: Vector3 = Vector3(5.0, 0.0, 3.0)
var path: PackedVector3Array = NavigationServer3D.map_get_path(
default_3d_map_rid,
start_position,
target_position,
true
)
# Basic query for a navigation path using the default navigation map.
func get_navigation_path(p_start_position: Vector3, p_target_position: Vector3) -> PackedVector3Array:
if not is_inside_tree():
return PackedVector3Array()
var default_map_rid: RID = get_world_3d().get_navigation_map()
var path: PackedVector3Array = NavigationServer3D.map_get_path(
default_map_rid,
p_start_position,
p_target_position,
true
)
return path
A returned ``path`` by the NavigationServer will be a ``PackedVector2Array`` for 2D or a ``PackedVector3Array`` for 3D.
These are just a memory-optimized ``Array`` of vector positions.
@@ -36,38 +36,45 @@ Creating new navigation regions
New NavigationRegion nodes will automatically register to the default world navigation map for their 2D/3D dimension.
The region RID can then be obtained from NavigationRegion Nodes with ``get_region_rid()``.
The region RID can then be obtained from NavigationRegion Nodes with ``get_rid()``.
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 2D GDScript
extends NavigationRegion2D
var navigationserver_region_rid: RID = get_rid()
.. code-tab:: gdscript 3D GDScript
extends NavigationRegion3D
var navigationserver_region_rid: RID = get_region_rid()
var navigationserver_region_rid: RID = get_rid()
New regions can also be created with the NavigationServer API and added to any existing map.
If regions are created with the NavigationServer API directly they need to be assigned a navigation map manually.
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 2D GDScript
extends Node2D
var new_2d_region_rid: RID = NavigationServer2D.region_create()
var default_2d_map_rid: RID = get_world_2d().get_navigation_map()
NavigationServer2D.region_set_map(new_2d_region_rid, default_2d_map_rid)
func _ready() -> void:
var new_region_rid: RID = NavigationServer2D.region_create()
var default_map_rid: RID = get_world_2d().get_navigation_map()
NavigationServer2D.region_set_map(new_region_rid, default_map_rid)
.. tabs::
.. code-tab:: gdscript GDScript
.. code-tab:: gdscript 3D GDScript
extends Node3D
var new_3d_region_rid: RID = NavigationServer3D.region_create()
var default_3d_map_rid: RID = get_world_3d().get_navigation_map()
NavigationServer3D.region_set_map(new_3d_region_rid, default_3d_map_rid)
func _ready() -> void:
var new_region_rid: RID = NavigationServer3D.region_create()
var default_map_rid: RID = get_world_3d().get_navigation_map()
NavigationServer3D.region_set_map(new_region_rid, default_map_rid)
.. note::
NavigationRegions can only be assigned to a single NavigationMap.
If an existing region is assigned to a new map it will leave the old map.
Navigation regions can only be assigned to a single navigation map.
If an existing region is assigned to a new navigation map it will leave the old map.