123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- .. _doc_navigation_using_navigationpaths:
- Using NavigationPaths
- =====================
- Obtaining a Navigationpath
- --------------------------
- Navigation paths can be directly queried from the NavigationServer and do not require any
- additional nodes or objects as long as the navigation map has a navigationmesh to work with.
- To obtain a 2D path, use ``NavigationServer2D.map_get_path(map, from, to, optimize, navigation_layers)``.
- To obtain a 3D path, use ``NavigationServer3D.map_get_path(map, from, to, optimize, navigation_layers)``.
- For more customizable navigation path queries that require additional setup see :ref:`doc_navigation_using_navigationpathqueryobjects`.
- One of the required parameters for the query is the RID of the navigation map.
- Each game ``World`` has a default navigation map automatically created.
- The default navigation maps can be retrieved with ``get_world_2d().get_navigation_map()`` from
- any Node2D inheriting node or ``get_world_3d().get_navigation_map()`` from any Node3D inheriting node.
- The second and third parameters are the starting position and the target position as Vector2 for 2D or Vector3 for 3D.
- If the ``optimized`` parameter is ``true``, path positions will be shortened along polygon
- corners with an additional funnel algorithm pass. This works well for free movement
- on navigationmeshes with unequal sized polygons as the path will hug around corners
- along the polygon corridor found by the A* algorithm. With small cells the A* algorithm
- creates a very narrow funnel corridor that can create ugly corner paths when used with grids.
- If the ``optimized`` parameter is ``false``, path positions will be placed at the center of each polygon edge.
- This works well for pure grid movement on navmeshes with equal sized polygons as the path will go through the center of the grid cells.
- Outside of grids due to polygons often covering large open areas with a single, long edge this can create paths with unnecessary long detours.
- .. tabs::
- .. code-tab:: gdscript 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
- 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
- )
- 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.
- All position vectors inside the array are guaranteed to be inside a NavigationPolygon or NavigationMesh.
- The path array, if not empty, has the navigationmesh position closest to the starting position at the first index ``path[0]`` position.
- The closest available navigationmesh position to the target position is the last index ``path[path.size()-1]`` position.
- All index between are the pathpoints that an actor should follow to reach the target without leaving the navigation mesh.
- .. note::
- If the target position is on a different navigation mesh that is not merged or connected
- the navigation path will lead to the closest possible position on the starting position navigation mesh.
- The following script moves a Node3D inheriting node along a navigation path using
- the default navigation map by setting the target position with ``set_movement_target()``.
- .. tabs::
- .. code-tab:: gdscript GDScript
- var movement_speed: float = 4.0
- var movement_delta: float
- var path_point_margin: float = 0.5
- var default_3d_map_rid: RID = get_world_3d().get_navigation_map()
- var current_path_index: int = 0
- var current_path_point: Vector3
- var current_path: PackedVector3Array
- func set_movement_target(target_position: Vector3):
- var start_position: Vector3 = global_transform.origin
- current_path = NavigationServer3D.map_get_path(
- default_3d_map_rid,
- start_position,
- target_position,
- true
- )
- if not current_path.is_empty():
- current_path_index = 0
- current_path_point = current_path[0]
- func _physics_process(delta):
- if current_path.is_empty():
- return
- movement_delta = move_speed * delta
- if global_transform.origin.distance_to(current_path_point) <= path_point_margin:
- current_path_index += 1
- if current_path_index >= current_path.size():
- current_path = []
- current_path_index = 0
- current_path_point = global_transform.origin
- return
- current_path_point = current_path[current_path_index]
- var new_velocity: Vector3 = (current_path_point - global_transform.origin).normalized() * movement_delta
- global_transform.origin = global_transform.origin.move_toward(global_transform.origin + new_velocity, movement_delta)
|