navigation_introduction_3d.rst 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. .. _doc_navigation_overview_3d:
  2. 3D Navigation Overview
  3. ======================
  4. Godot provides multiple objects, classes and servers to facilitate grid-based or mesh-based navigation and pathfinding for 2D and 3D games.
  5. The following section provides a quick overview over all available navigation related objects in Godot for 3D scenes and their primary use.
  6. Godot provides the following objects and classes for 3D navigation:
  7. - :ref:`Astar3D<class_Astar3D>`
  8. ``Astar3D`` objects provide an option to find the shortest path in a graph of weighted **points**.
  9. The AStar3D class is best suited for cellbased 3D gameplay that does not require actors to reach any
  10. possible position within an area but only predefined, distinct positions.
  11. - :ref:`NavigationServer3D<class_NavigationServer3D>`
  12. ``NavigationServer3D`` provides a powerful server API to find the shortest path between two positions
  13. on a area defined by a navigation mesh.
  14. The NavigationServer is best suited for 3D realtime gameplay that does require actors to reach any
  15. possible position within an navmesh defined area. Meshbased navigation scales well with large gameworlds
  16. as a large area can often be defined with a single polygon when it would require many, many grid cells.
  17. The NavigationServer holds different navigation maps that each consist of regions that hold navigation mesh
  18. data. Agents can be placed on a map for avoidance calculation. RIDs are used to reference the internal maps,
  19. regions and agents when communicating with the server.
  20. The following NavigationServer RID types are available.
  21. - NavMap RID
  22. Reference to a specific navigation map that holds regions and agents.
  23. The map will attempt to join changed navigation meshes of regions by proximity.
  24. The map will synchronize regions and agents each physics frame.
  25. - NavRegion RID
  26. Reference to a specific navigation region that can hold navigation mesh data.
  27. The region can be enabled / disabled or the use restricted with a navigationlayer bitmask.
  28. - NavLink RID
  29. Reference to a specific navigation link that connects two navigation mesh positions over arbitrary distances.
  30. - NavAgent RID
  31. Reference to a specific avoidance agent with a radius value use solely in avoidance.
  32. The following SceneTree Nodes are available as helpers to work with the NavigationServer3D API.
  33. - :ref:`NavigationRegion3D<class_NavigationRegion3D>` Node
  34. A Node that holds a Navigation Mesh resource that defines a navigation mesh for the NavigationServer3D.
  35. - The region can be enabled / disabled.
  36. - The use in pathfinding can be further restricted through the navigationlayers bitmask.
  37. - Regions can join their navigation meshes by proximity for a combined navigation mesh.
  38. - :ref:`NavigationLink3D<class_NavigationLink3D>` Node
  39. A Node that connects two positions on navigation mesh over arbitrary distances for pathfinding.
  40. - The link can be enabled / disabled.
  41. - The link can be made one-way or bidirectional.
  42. - The use in pathfinding can be further restricted through the navigationlayers bitmask.
  43. Links tell the pathfinding that a connection exists and at what cost. The actual agent handling and movement needs to happen in custom scripts.
  44. - :ref:`NavigationAgent3D<class_NavigationAgent3D>` Node
  45. An optional helper Node to facilitate common NavigationServer3D API calls for pathfinding and avoidance for
  46. a Node3D inheriting parent Node.
  47. - :ref:`NavigationObstacle3D<class_NavigationObstacle3D>` Node
  48. A Node that acts as an agent with avoidance radius, to work it needs to be added under a Node3D
  49. inheriting parent Node. Obstacles are intended as a last resort option for constantly moving objects
  50. that cannot be re(baked) to a navigation mesh efficiently. This node also only works if RVO processing
  51. is being used.
  52. The 3D navigation meshes are defined with the following resources:
  53. - :ref:`NavigationMesh<class_NavigationMesh>` Resource
  54. A resource that holds 3D navigation mesh data and provides 3D geometry baking options to define navigation
  55. areas inside the Editor as well as at runtime.
  56. - The NavigationRegion3D Node uses this resource to define its navigation area.
  57. - The NavigationServer3D uses this resource to update navmesh of individual regions.
  58. - The GridMap Editor uses this resource when specific navigation meshes are defined for each gridcell.
  59. .. seealso::
  60. You can see how 3D navigation works in action using the
  61. `3D Navigation demo project <https://github.com/godotengine/godot-demo-projects/tree/master/3d/navigation>`__.
  62. Setup for 3D scene
  63. ------------------
  64. The following steps show how to setup a minimum viable navigation in 3D that uses the NavigationServer3D and
  65. a NavigationAgent3D for path movement.
  66. #. Add a NavigationRegion3D Node to the scene.
  67. #. Click on the region node and add a new :ref:`NavigationMesh<class_NavigationMesh>` Resource to
  68. the region node.
  69. .. image:: img/nav_3d_min_setup_step1.png
  70. #. Add a new MeshInstance3D node as a child of the region node.
  71. #. Select the MeshInstance3D node and add a new PlaneMesh and increase the xy size to 10.
  72. #. Select the region node again and press the "Bake Navmesh" button on the top bar.
  73. .. image:: img/nav_3d_min_setup_step2.png
  74. #. Now a transparent navigation mesh appeared that hovers some distance on top the planemesh.
  75. .. image:: img/nav_3d_min_setup_step3.png
  76. #. Add a CharacterBody3D node in the scene with a basic collision shape and some mesh for visuals.
  77. #. Add a NavigationAgent3D node below the character node.
  78. .. image:: img/nav_3d_min_setup_step4.webp
  79. #. Add a script to the CharacterBody3D node with the following content. We make sure to set a
  80. movement target after the scene has fully loaded and the NavigationServer had time to sync.
  81. Also, add a Camera3D and some light and environment to see something.
  82. .. tabs::
  83. .. code-tab:: gdscript GDScript
  84. extends CharacterBody3D
  85. var movement_speed: float = 2.0
  86. var movement_target_position: Vector3 = Vector3(-3.0,0.0,2.0)
  87. @onready var navigation_agent: NavigationAgent3D = $NavigationAgent3D
  88. func _ready():
  89. # These values need to be adjusted for the actor's speed
  90. # and the navigation layout.
  91. navigation_agent.path_desired_distance = 0.5
  92. navigation_agent.target_desired_distance = 0.5
  93. # Make sure to not await during _ready.
  94. call_deferred("actor_setup")
  95. func actor_setup():
  96. # Wait for the first physics frame so the NavigationServer can sync.
  97. await get_tree().physics_frame
  98. # Now that the navigation map is no longer empty, set the movement target.
  99. set_movement_target(movement_target_position)
  100. func set_movement_target(movement_target: Vector3):
  101. navigation_agent.set_target_position(movement_target)
  102. func _physics_process(delta):
  103. if navigation_agent.is_navigation_finished():
  104. return
  105. var current_agent_position: Vector3 = global_position
  106. var next_path_position: Vector3 = navigation_agent.get_next_path_position()
  107. var new_velocity: Vector3 = next_path_position - current_agent_position
  108. new_velocity = new_velocity.normalized()
  109. new_velocity = new_velocity * movement_speed
  110. velocity = new_velocity
  111. move_and_slide()
  112. .. code-tab:: csharp C#
  113. using Godot;
  114. public partial class MyCharacterBody3D : CharacterBody3D
  115. {
  116. private NavigationAgent3D _navigationAgent;
  117. private float _movementSpeed = 2.0f;
  118. private Vector3 _movementTargetPosition = new Vector3(-3.0f, 0.0f, 2.0f);
  119. public Vector3 MovementTarget
  120. {
  121. get { return _navigationAgent.TargetPosition; }
  122. set { _navigationAgent.TargetPosition = value; }
  123. }
  124. public override void _Ready()
  125. {
  126. base._Ready();
  127. _navigationAgent = GetNode<NavigationAgent3D>("NavigationAgent3D");
  128. // These values need to be adjusted for the actor's speed
  129. // and the navigation layout.
  130. _navigationAgent.PathDesiredDistance = 0.5f;
  131. _navigationAgent.TargetDesiredDistance = 0.5f;
  132. // Make sure to not await during _Ready.
  133. Callable.From(ActorSetup).CallDeferred();
  134. }
  135. public override void _PhysicsProcess(double delta)
  136. {
  137. base._PhysicsProcess(delta);
  138. if (_navigationAgent.IsNavigationFinished())
  139. {
  140. return;
  141. }
  142. Vector3 currentAgentPosition = GlobalTransform.Origin;
  143. Vector3 nextPathPosition = _navigationAgent.GetNextPathPosition();
  144. Vector3 newVelocity = (nextPathPosition - currentAgentPosition).Normalized();
  145. newVelocity *= _movementSpeed;
  146. Velocity = newVelocity;
  147. MoveAndSlide();
  148. }
  149. private async void ActorSetup()
  150. {
  151. // Wait for the first physics frame so the NavigationServer can sync.
  152. await ToSignal(GetTree(), SceneTree.SignalName.PhysicsFrame);
  153. // Now that the navigation map is no longer empty, set the movement target.
  154. MovementTarget = _movementTargetPosition;
  155. }
  156. }
  157. .. note::
  158. On the first frame the NavigationServer map has not synchronized region data and any path query
  159. will return empty. Await one frame to pause scripts until the NavigationServer had time to sync.