navigation_using_navigationpaths.rst 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. .. _doc_navigation_using_navigationpaths:
  2. Using NavigationPaths
  3. =====================
  4. Obtaining a Navigationpath
  5. --------------------------
  6. Navigation paths can be directly queried from the NavigationServer and do not require any
  7. additional nodes or objects as long as the navigation map has a navigationmesh to work with.
  8. To obtain a 2D path, use ``NavigationServer2D.map_get_path(map, from, to, optimize, navigation_layers)``.
  9. To obtain a 3D path, use ``NavigationServer3D.map_get_path(map, from, to, optimize, navigation_layers)``.
  10. One of the required parameters for the query is the RID of the navigation map.
  11. Each game ``World`` has a default navigation map automatically created.
  12. The default navigation maps can be retrieved with ``get_world_2d().get_navigation_map()`` from
  13. any Node2D inheriting node or ``get_world_3d().get_navigation_map()`` from any Node3D inheriting node.
  14. The second and third parameters are the starting position and the target position as Vector2 for 2D or Vector3 for 3D.
  15. If the ``optimized`` parameter is ``true``, path positions will be shortened along polygon
  16. corners with an additional funnel algorithm pass. This works well for free movement
  17. on navigationmeshes with unequal sized polygons as the path will hug around corners
  18. along the polygon corridor found by the A* algorithm. With small cells the A* algorithm
  19. creates a very narrow funnel corridor that can create ugly corner paths when used with grids.
  20. If the ``optimized`` parameter is ``false``, path positions will be placed at the center of each polygon edge.
  21. 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.
  22. Outside of grids due to polygons often covering large open areas with a single, long edge this can create paths with unnecessary long detours.
  23. .. tabs::
  24. .. code-tab:: gdscript GDScript
  25. extends Node2D
  26. # basic query for a navigation path in 2D using the default navigation map
  27. var default_2d_map_rid : RID = get_world_2d().get_navigation_map()
  28. var start_position : Vector2 = Vector2(0.0, 0.0)
  29. var target_position : Vector2 = Vector2(5.0, 0.0)
  30. var path : PackedVector2Array = NavigationServer2D.map_get_path(
  31. default_2d_map_rid,
  32. start_position,
  33. target_position,
  34. true
  35. )
  36. .. tabs::
  37. .. code-tab:: gdscript GDScript
  38. extends Node3D
  39. # basic query for a navigation path in 3D using the default navigation map
  40. var default_3d_map_rid : RID = get_world_3d().get_navigation_map()
  41. var start_position : Vector3 = Vector3(0.0, 0.0, 0.0)
  42. var target_position : Vector3 = Vector3(5.0, 0.0, 3.0)
  43. var path : PackedVector3Array = NavigationServer3D.map_get_path(
  44. default_3d_map_rid,
  45. start_position,
  46. target_position,
  47. true
  48. )
  49. A returned ``path`` by the NavigationServer will be a ``PackedVector2Array`` for 2D or a ``PackedVector3Array`` for 3D.
  50. These are just a memory-optimized ``Array`` of vector positions.
  51. All position vectors inside the array are guaranteed to be inside a NavigationPolygon or NavigationMesh.
  52. The path array, if not empty, has the navigationmesh position closest to the starting position at the first index ``path[0]`` position.
  53. The closest available navigationmesh position to the target position is the last index ``path[path.size()-1]`` position.
  54. All index between are the pathpoints that an actor should follow to reach the target without leaving the navigation mesh.
  55. .. note::
  56. If the target position is on a different navigation mesh that is not merged or connected
  57. the navigation path will lead to the closest possible position on the starting position navigation mesh.
  58. The following script moves a Node3D inheriting node along a navigation path using
  59. the default navigation map by setting the target position with ``set_movement_target()``.
  60. .. tabs::
  61. .. code-tab:: gdscript GDScript
  62. var movement_speed : float = 4.0
  63. var movement_delta : float
  64. var path_point_margin : float = 0.5
  65. var default_3d_map_rid : RID = get_world_3d().get_navigation_map()
  66. var current_path_index : int = 0
  67. var current_path_point : Vector3
  68. var current_path : PackedVector3Array
  69. func set_movement_target(target_position : Vector3):
  70. var start_position : Vector3 = global_transform.origin
  71. current_path = NavigationServer3D.map_get_path(
  72. default_3d_map_rid,
  73. start_position,
  74. target_position,
  75. true
  76. )
  77. if not current_path.is_empty():
  78. current_path_index = 0
  79. current_path_point = current_path[0]
  80. func _physics_process(delta):
  81. if current_path.is_empty():
  82. return
  83. movement_delta = move_speed * delta
  84. if global_transform.origin.distance_to(current_path_point) <= path_point_margin:
  85. current_path_index += 1
  86. if current_path_index >= current_path.size():
  87. current_path = []
  88. current_path_index = 0
  89. current_path_point = global_transform.origin
  90. return
  91. current_path_point = current_path[current_path_index]
  92. var new_velocity : Vector3 = (current_path_point - global_transform.origin).normalized() * movement_delta
  93. global_transform.origin = global_transform.origin.move_toward(global_transform.origin + new_velocity, movement_delta)