diff --git a/tutorials/navigation/img/bake_navmesh.png b/tutorials/navigation/img/bake_navmesh.png deleted file mode 100644 index 8b149ad1124b..000000000000 Binary files a/tutorials/navigation/img/bake_navmesh.png and /dev/null differ diff --git a/tutorials/navigation/img/baked_navmesh.png b/tutorials/navigation/img/baked_navmesh.png deleted file mode 100644 index a13fd3f7e1d8..000000000000 Binary files a/tutorials/navigation/img/baked_navmesh.png and /dev/null differ diff --git a/tutorials/navigation/img/nav_2d_min_setup_step1.png b/tutorials/navigation/img/nav_2d_min_setup_step1.png new file mode 100644 index 000000000000..1b102cb44e30 Binary files /dev/null and b/tutorials/navigation/img/nav_2d_min_setup_step1.png differ diff --git a/tutorials/navigation/img/nav_2d_min_setup_step2.png b/tutorials/navigation/img/nav_2d_min_setup_step2.png new file mode 100644 index 000000000000..08b0765afc4b Binary files /dev/null and b/tutorials/navigation/img/nav_2d_min_setup_step2.png differ diff --git a/tutorials/navigation/img/nav_2d_min_setup_step3.png b/tutorials/navigation/img/nav_2d_min_setup_step3.png new file mode 100644 index 000000000000..be0ee27ae525 Binary files /dev/null and b/tutorials/navigation/img/nav_2d_min_setup_step3.png differ diff --git a/tutorials/navigation/img/nav_3d_min_setup_step1.png b/tutorials/navigation/img/nav_3d_min_setup_step1.png new file mode 100644 index 000000000000..6c1d3cc4a5f4 Binary files /dev/null and b/tutorials/navigation/img/nav_3d_min_setup_step1.png differ diff --git a/tutorials/navigation/img/nav_3d_min_setup_step2.png b/tutorials/navigation/img/nav_3d_min_setup_step2.png new file mode 100644 index 000000000000..bec406d8766c Binary files /dev/null and b/tutorials/navigation/img/nav_3d_min_setup_step2.png differ diff --git a/tutorials/navigation/img/nav_3d_min_setup_step3.png b/tutorials/navigation/img/nav_3d_min_setup_step3.png new file mode 100644 index 000000000000..5d4cd743e170 Binary files /dev/null and b/tutorials/navigation/img/nav_3d_min_setup_step3.png differ diff --git a/tutorials/navigation/img/nav_3d_min_setup_step4.png b/tutorials/navigation/img/nav_3d_min_setup_step4.png new file mode 100644 index 000000000000..8daf6c7e4138 Binary files /dev/null and b/tutorials/navigation/img/nav_3d_min_setup_step4.png differ diff --git a/tutorials/navigation/index.rst b/tutorials/navigation/index.rst index d27dcc39495d..9ad6f79e3c0c 100644 --- a/tutorials/navigation/index.rst +++ b/tutorials/navigation/index.rst @@ -5,4 +5,5 @@ Navigation :maxdepth: 1 :name: toc-learn-features-navigation - real_time_navigation_3d + navigation_introduction_2d.rst + navigation_introduction_3d.rst diff --git a/tutorials/navigation/navigation_introduction_2d.rst b/tutorials/navigation/navigation_introduction_2d.rst new file mode 100644 index 000000000000..cc23bc890d46 --- /dev/null +++ b/tutorials/navigation/navigation_introduction_2d.rst @@ -0,0 +1,147 @@ +.. _doc_navigation_overview_2d: + +Introduction +=================== + +Godot provides multiple objects, classes and servers to facilitate grid-based- or mesh-based navigation +and pathfinding for 2D and 3D games. The following section provides a quick overview over all available +navigation related objects in Godot for 2D scenes and their primary use. + +2D Navigation Overview +---------------------- + +Godot provides the following objects and classes for 2D navigation: + +- :ref:`Astar2D` + ``Astar2D`` objects provide an option to find the shortest path in a graph of weighted **points**. + + The AStar2D class is best suited for cellbased 2D gameplay that does not require actors to reach any possible position within an area but only predefined, distinct positions. + +- :ref:`NavigationServer2D` + ``NavigationServer2D`` provides a powerful server API to find the shortest path between two positions on a navigationmesh defined area. + + The NavigationServer is best suited for 2D realtime gameplay that does require actors to reach any possible position within an navmesh defined area. + Meshbased navigation scales well with large gameworlds as a large area can often be defined with a single polygon when it would require many, many grid cells. + + The NavigationServer holds different navigation maps that each consist of regions that hold navigationmesh data. + Agents can be placed on a map for avoidance calculation. + RIDs are used to reference the internal maps, regions and agents when communicating with the server. + + The following NavigationServer RID types are available. + - NavMap RID + Reference to a specific navigation map that holds regions and agents. + The map will attempt to join changed navigationmeshes of regions by proximity. + The map will synchronise regions and agents each physics frame. + - NavRegion RID + Reference to a specific navigation region that can hold navigationmesh data. + The region can be enabled / disabled or the use restricted with a navigationlayer bitmask. + - NavAgent RID + Reference to a specific avoidance agent with a radius value use solely in avoidance. + +The following SceneTree Nodes are available as helpers to work with the NavigationServer2D API. + +- :ref:`NavigationRegion2D` Node + A Node that holds a NavigationPolygon resource that defines a navigationmesh for the NavigationServer2D. + The region can be enabled / disabled. + The use in pathfinding can be further restricted through the navigationlayers bitmask. + Regions can join their navigationmeshes by proximity for a combined navigationmesh. + +- :ref:`NavigationAgent2D` Node + An optional helper Node to facilitate common NavigationServer2D API calls for pathfinding and avoidance + for a Node2D inheriting parent Node. + +- :ref:`NavigationObstacle2D` Node + A Node that acts as an agent with avoidance radius, to work it just needs to be added under a Node2D + inheriting parent Node. Obstacles are intended as a last resort option for constantly moving objects + that cannot be re(baked) to a navigationmesh efficiently. This node also only works if RVO processing + is being used. + +The 2D navigationmeshes are defined with the following resources: + +- :ref:`NavigationPolygon` Resource + A resource that holds 2D navigationmesh data and provides polygon drawtools to define navigation areas inside the Editor as well as at runtime. + + - The NavigationRegion2D Node uses this resource to define its navigation area. + - The NavigationServer2D uses this resource to update navmesh of individual regions. + - The TileSet Editor creates and uses this resource internally when defining tile navigation areas. + +Setup for 2D scene +------------------ + +The following steps show the basic setup for a minimum viable navigation in 2D that uses the +NavigationServer2D and a NavigationAgent2D for path movement. + +1.) Add a NavigationRegion2D Node to the scene. + +2.) Click on the region node and add a new NavigationPolygon Resource to the region node + +.. image:: img/nav_2d_min_setup_step1.png + +3.) Define the moveable navigation area with the NavigationPolygon draw tool + +.. image:: img/nav_2d_min_setup_step2.png + +.. note:: + + The navigation mesh defines the area where an actor can stand and move with its center. + Leave enough margin between the navpolygon edges and collision objects to not get path following actors repeatedly stuck on collision. + +4.) Add a CharacterBody2D below the region node with a basic collision shape and a sprite or mesh for visuals. + +5.) Add a NavigationAgent2D node below the character node + +.. image:: img/nav_2d_min_setup_step3.png + +6.) Add the following script to the CharacterBody2D node. Set a movement target with the set_movement_target() function after the scene has fully loaded and the NavigationServer had time to sync. + +.. note:: + + On the first frame the NavigationServer map has not synchronised region data and any path query will return empty. + Use ``await get_tree().physics_frame`` to pause scripts until the NavigationServer had time to sync. + +.. tabs:: + .. code-tab:: gdscript GDScript + + extends CharacterBody2D + + var movement_speed : float = 200.0 + var movement_target_position : Vector2 = Vector2(60.0,180.0) + + @onready var navigation_agent : NavigationAgent2D = $NavigationAgent2D + + func _ready(): + # these values need to be adjusted for the actor's speed + # and the navpolygon layout as each crossed edge will create a path point + # If the actor moves to fast it might overshoot + # multiple path points in one frame and start to backtrack + navigation_agent.path_desired_distance = 4.0 + navigation_agent.target_desired_distance = 4.0 + + # make a deferred function call to assure the entire Scenetree is loaded + call_deferred("actor_setup") + + func actor_setup(): + # wait for the first physics frame so the NavigationServer can sync + await get_tree().physics_frame + + # now that the navigation map is no longer empty set the movement target + set_movement_target(movement_target_position) + + func set_movement_target(movement_target : Vector2): + navigation_agent.set_target_location(movement_target) + + func _physics_process(delta): + + if navigation_agent.is_target_reached(): + return + + var current_agent_position : Vector2 = global_transform.origin + var next_path_position : Vector2 = navigation_agent.get_next_location() + + var new_velocity : Vector2 = next_path_position - current_agent_position + new_velocity = new_velocity.normalized() + new_velocity = new_velocity * movement_speed + + set_velocity(new_velocity) + + move_and_slide() diff --git a/tutorials/navigation/navigation_introduction_3d.rst b/tutorials/navigation/navigation_introduction_3d.rst new file mode 100644 index 000000000000..17283b472ee4 --- /dev/null +++ b/tutorials/navigation/navigation_introduction_3d.rst @@ -0,0 +1,134 @@ +.. _doc_navigation_overview_3d: + +Introduction +=================== + +Godot provides multiple objects, classes and servers to facilitate grid-based- or mesh-based navigation +and pathfinding for 2D and 3D games. The following section provides a quick overview over all available +navigation related objects in Godot for 3D scenes and their primary use. + +3D Navigation Overview +---------------------- + +Godot provides the following objects and classes for 3D navigation: + +- :ref:`Astar3D` + ``Astar3D`` objects provide an option to find the shortest path in a graph of weighted **points**. + + The AStar3D class is best suited for cellbased 3D gameplay that does not require actors to reach any + possible position within an area but only predefined, distinct positions. + +- :ref:`NavigationServer3D` + ``NavigationServer3D`` provides a powerful server API to find the shortest path between two positions + on a navigationmesh defined area. + + The NavigationServer is best suited for 3D realtime gameplay that does require actors to reach any + possible position within an navmesh defined area. Meshbased navigation scales well with large gameworlds + as a large area can often be defined with a single polygon when it would require many, many grid cells. + + The NavigationServer holds different navigation maps that each consist of regions that hold navigationmesh + data. Agents can be placed on a map for avoidance calculation. RIDs are used to reference the internal maps, + regions and agents when communicating with the server. + + The following NavigationServer RID types are available. + - NavMap RID + Reference to a specific navigation map that holds regions and agents. + The map will attempt to join changed navigationmeshes of regions by proximity. + The map will synchronise regions and agents each physics frame. + - NavRegion RID + Reference to a specific navigation region that can hold navigationmesh data. + The region can be enabled / disabled or the use restricted with a navigationlayer bitmask. + - NavAgent RID + Reference to a specific avoidance agent with a radius value use solely in avoidance. + +The following SceneTree Nodes are available as helpers to work with the NavigationServer3D API. + +- :ref:`NavigationRegion3D` Node + A Node that holds a NavigationMesh resource that defines a navigationmesh for the NavigationServer3D. + The region can be enabled / disabled. + The use in pathfinding can be further restricted through the navigationlayers bitmask. + Regions can join their navigationmeshes by proximity for a combined navigationmesh. + +- :ref:`NavigationAgent3D` Node + An optional helper Node to facilitate common NavigationServer3D API calls for pathfinding and avoidance for + a Node3D inheriting parent Node. + +- :ref:`NavigationObstacle3D` Node + A Node that acts as an agent with avoidance radius, to work it just needs to be added under a Node3D + inheriting parent Node. Obstacles are intended as a last resort option for constantly moving objects + that cannot be re(baked) to a navigationmesh efficiently. This node also only works if RVO processing + is being used. + +The 3D navigationmeshes are defined with the following resources: + +- :ref:`NavigationMesh` Resource + A resource that holds 3D navigationmesh data and provides 3D geometry baking options to define navigation + areas inside the Editor as well as at runtime. + + - The NavigationRegion3D Node uses this resource to define its navigation area. + - The NavigationServer3D uses this resource to update navmesh of individual regions. + - The GridMap Editor uses this resource when specific navigationmeshes are defined for each gridcell. + +Setup for 3D scene +------------------ + +The following steps show how to setup a minimum viable navigation in 3D that uses the NavigationServer3D and +a NavigationAgent3D for path movement. + +1.) Add a NavigationRegion3D Node to the scene. + +2.) Click on the region node and add a new NavigationMesh Resource to the region node + +.. image:: img/nav_3d_min_setup_step1.png + +3.) Add a new MeshInstance node as a child of the region node + +4.) Select the meshinstance node and add a new PlaneMesh and increase the xy size to 10. + +5.) Select the region node again and press the "Bake Navmesh" button on the top bar + +.. image:: img/nav_3d_min_setup_step2.png + +7.) Now a transparent navigationmesh appeared that hovers some distance on top the planemesh. + +.. image:: img/nav_3d_min_setup_step3.png + +8.) Add a CharacterBody3D below the region node with a basic collision shape and some mesh for visuals. + +9.) Add a NavigationAgent3D node below the character node + +.. image:: img/nav_3d_min_setup_step4.png + +10.) Add a script to the CharacterBody3D node with the following content. + +.. tabs:: + .. code-tab:: gdscript GDScript + + extends CharacterBody3D + + var movement_speed : float = 4.0 + + @onready var navigation_agent = $NavigationAgent3D + + func set_movement_target(movement_target : Vector3): + navigation_agent.set_target_location(movement_target) + + func _physics_process(delta): + + var current_agent_position : Vector3 = global_transform.origin + var next_path_position : Vector3 = navigation_agent.get_next_location() + + var new_velocity : Vector3 = next_path_position - current_agent_position + new_velocity = new_velocity.normalized() + new_velocity = new_velocity * movement_speed + + set_velocity(new_velocity) + move_and_slide() + +Set a movement target with the set_movement_target() function after the scene has fully loaded. +Also add a Camera3D and some light and environment to see something. + +.. warning:: + + On the first frame the NavigationServer map has not synchronised region data and any path query will return empty. + Use ``await get_tree().physics_frame`` to pause scripts until the NavigationServer had time to sync. diff --git a/tutorials/navigation/real_time_navigation_3d.rst b/tutorials/navigation/real_time_navigation_3d.rst deleted file mode 100644 index cae201db45fc..000000000000 --- a/tutorials/navigation/real_time_navigation_3d.rst +++ /dev/null @@ -1,92 +0,0 @@ -.. _doc_real_time_navigation_3d: - -Real Time Navigation (3D) -========================= - -Introduction ------------- - -Pathfinding in a 3D environment is crucial for many games, it's commonly -how non directly controlled characters or entities find their way around -an environment. Godot provides several nodes for this purpose: - -- :ref:`NavigationRegion3D` -- :ref:`NavigationAgent3D` -- :ref:`NavigationObstacle3D` - -The map and navigation regions ------------------------------- - -The "map" is the entire world for navigation, it's similar to "space" for -the physics engine. It's comprised of navigation regions, these regions -define what parts of the world that can be navigated around by navigation -agents. - -To create a navigation region add the `NavigationRegion3D` -node to a 3D scene. Next in the inspector for that region create or add a -:ref:`NavigationMesh`. The navmesh contains options -for how it will be generated when it's baked. The geometry options control -which nodes, and types of nodes, are used to bake the mesh. A full -description of each setting and how it works can be found in the :ref:`NavigationMesh class reference`. - -Once the settings have been properly configured press the "Bake NavMesh" -button at the top of the inspector to generate it. - -.. image:: img/bake_navmesh.png - -.. note:: - - It can also be generated at runtime using the `bake_navigation_region()` - method of the navigation region node. - -Once the mesh has finished generating you should see the transparent -navigation mesh above the areas in the scene that can be navigated to. - -.. image:: img/baked_navmesh.png - -Keep in mind that the navmesh shows where the center of an entity can -go. For example, if you set the agent radius to 0.5 then the -navigation mesh will have a distance of 0.5 from any ledges or walls -to prevent clipping into the wall or hanging off of the edge. - -Navigation agents can moved from one region to another if they are next -to each other. Additionally A baked navmesh can be moved at runtime and -agents will still be able to navigate onto it from another region. -For example, navigating onto a moving platform that has stopped will work. - -NavigationAgent3D ------------------ - -Navigation agent nodes are what actually does the pathfinding in a scene, -one can be attached to the root node of an entity that needs to navigate. - -To have it pathfind use its `set_target_location` method. Once the target -has been set a path will be generated to the node using navigation regions, -with several points on the way to the final destination. - -RVO processing --------------- - -RVO stands for reciprocal velocity obstacle. RVO processing is a way to -pathfind while taking into account other agents and physics bodies that -are also moving. - -To use it set a target like normal. Then an agent needs to fetch its next -nav path location, and compute its velocity to that location. Instead -of using that value to move use it to set the velocity on the agent -with `set_velocity`. Then a new velocity that takes into account other -agents and obstacles is generated and emitted with the signal `velocity_computed`. - -However agents can only take into account a set number of other nearby -agents, this is the :ref:`max neighbors` -property of an agent and can be adjusted. This is **not** a limit for -how many agents can use a navigation region at the same time. - -NavigationObstacle3D --------------------- - -This node is used to mark physics bodies that move around a navigation area -that agents need to avoid (this will only work if you use RVO processing). -For example, this node would be useful for pieces of debris in a destructible -environment. Add it as the child of a physics body and navigation agent -nodes will avoid it while pathfinding.