|
@@ -3,8 +3,8 @@
|
|
Using NavigationMeshes
|
|
Using NavigationMeshes
|
|
======================
|
|
======================
|
|
|
|
|
|
-2D and 3D version of the navigation mesh are available as
|
|
|
|
-:ref:`NavigationPolygon<class_NavigationPolygon>` and
|
|
|
|
|
|
+2D and 3D version of the navigation mesh are available as
|
|
|
|
+:ref:`NavigationPolygon<class_NavigationPolygon>` and
|
|
:ref:`NavigationMesh<class_NavigationMesh>` respectively.
|
|
:ref:`NavigationMesh<class_NavigationMesh>` respectively.
|
|
|
|
|
|
.. _doc_navigation_navmesh_baking:
|
|
.. _doc_navigation_navmesh_baking:
|
|
@@ -12,7 +12,7 @@ Using NavigationMeshes
|
|
Creating 2D NavigationMeshes
|
|
Creating 2D NavigationMeshes
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
-Navigation meshes in the 2D editor are created with the help of the NavigationPolygon draw tools
|
|
|
|
|
|
+Navigation meshes in the 2D editor are created with the help of the NavigationPolygon draw tools
|
|
that appear in the top bar of the editor when a NavigationRegion2D is selected.
|
|
that appear in the top bar of the editor when a NavigationRegion2D is selected.
|
|
|
|
|
|
.. image:: img/nav_polydrawtool.png
|
|
.. image:: img/nav_polydrawtool.png
|
|
@@ -32,16 +32,16 @@ Outlines, as the name would suggest, cannot intersect each other or have any ove
|
|
.. image:: img/nav_polyoutlinefail.png
|
|
.. image:: img/nav_polyoutlinefail.png
|
|
|
|
|
|
Outline layouts like seen in this picture will fail the convex partitioning required by the navigation mesh generation.
|
|
Outline layouts like seen in this picture will fail the convex partitioning required by the navigation mesh generation.
|
|
-In this layout cases the outline tool cannot be used. Use the :ref:`Geometry2D<class_Geometry2D>` class for
|
|
|
|
|
|
+In this layout cases the outline tool cannot be used. Use the :ref:`Geometry2D<class_Geometry2D>` class for
|
|
polygon merge or intersect operations to create a valid merged mesh for navigation.
|
|
polygon merge or intersect operations to create a valid merged mesh for navigation.
|
|
|
|
|
|
.. note::
|
|
.. note::
|
|
|
|
|
|
- The NavigationServer does not connect navigation mesh islands from the same NavigationMesh resource.
|
|
|
|
|
|
+ The NavigationServer does not connect navigation mesh islands from the same NavigationMesh resource.
|
|
Do not create multiple disconnected islands in the same NavigationRegion2D and NavPoly resource if they should be later connected.
|
|
Do not create multiple disconnected islands in the same NavigationRegion2D and NavPoly resource if they should be later connected.
|
|
|
|
|
|
For 2D no similar navigation mesh baking with geometry parsing exists like in 3D.
|
|
For 2D no similar navigation mesh baking with geometry parsing exists like in 3D.
|
|
-The Geometry2D class functions for offset, merge, intersect and clip can be used
|
|
|
|
|
|
+The Geometry2D class functions for offset, merge, intersect and clip can be used
|
|
to shrink or enlarge existing NavigationPolygons to different actor sizes.
|
|
to shrink or enlarge existing NavigationPolygons to different actor sizes.
|
|
|
|
|
|
Creating 3D NavigationMeshes
|
|
Creating 3D NavigationMeshes
|
|
@@ -49,18 +49,18 @@ Creating 3D NavigationMeshes
|
|
|
|
|
|
.. image:: img/baked_navmesh.png
|
|
.. image:: img/baked_navmesh.png
|
|
|
|
|
|
-Navigation meshes in the 3D editor are created with the help of the
|
|
|
|
-:ref:`NavigationMeshGenerator<class_NavigationMeshGenerator>` singleton
|
|
|
|
|
|
+Navigation meshes in the 3D editor are created with the help of the
|
|
|
|
+:ref:`NavigationMeshGenerator<class_NavigationMeshGenerator>` singleton
|
|
and the NavigationMesh bake settings that appear in the editor inspector.
|
|
and the NavigationMesh bake settings that appear in the editor inspector.
|
|
|
|
|
|
NavigationMesh baking is the process of creating a simplified mesh used for pathfinding out of (complex) 3D level geometry.
|
|
NavigationMesh baking is the process of creating a simplified mesh used for pathfinding out of (complex) 3D level geometry.
|
|
-For this process Godot parses scene geometry and hands the raw mesh or collision data to the
|
|
|
|
|
|
+For this process Godot parses scene geometry and hands the raw mesh or collision data to the
|
|
third-party ReCast library for processing and creation of the final navigationmesh.
|
|
third-party ReCast library for processing and creation of the final navigationmesh.
|
|
|
|
|
|
-The resulting NavigationMesh is an approximation of the source geometry surfaces
|
|
|
|
-for both performance and technical reasons. Do not expect the NavigationMesh
|
|
|
|
-to perfectly follow the original surfaces. Especially navigation polygons placed
|
|
|
|
-over ramps will not keep an equal distance to the ground surface. To align an
|
|
|
|
|
|
+The resulting NavigationMesh is an approximation of the source geometry surfaces
|
|
|
|
+for both performance and technical reasons. Do not expect the NavigationMesh
|
|
|
|
+to perfectly follow the original surfaces. Especially navigation polygons placed
|
|
|
|
+over ramps will not keep an equal distance to the ground surface. To align an
|
|
actor perfectly with the ground use other means like physics.
|
|
actor perfectly with the ground use other means like physics.
|
|
|
|
|
|
.. warning::
|
|
.. warning::
|
|
@@ -76,22 +76,22 @@ If the navmesh resource is already prepared, the region can be updated with the
|
|
|
|
|
|
.. tabs::
|
|
.. tabs::
|
|
.. code-tab:: gdscript GDScript
|
|
.. code-tab:: gdscript GDScript
|
|
-
|
|
|
|
|
|
+
|
|
extends NavigationRegion3D
|
|
extends NavigationRegion3D
|
|
-
|
|
|
|
|
|
+
|
|
func update_navmesh():
|
|
func update_navmesh():
|
|
-
|
|
|
|
|
|
+
|
|
# use bake and update function of region
|
|
# use bake and update function of region
|
|
var on_thread : bool = true
|
|
var on_thread : bool = true
|
|
bake_navigation_mesh(on_thread)
|
|
bake_navigation_mesh(on_thread)
|
|
-
|
|
|
|
|
|
+
|
|
# or use the NavigationMeshGenerator Singleton
|
|
# or use the NavigationMeshGenerator Singleton
|
|
var navigationmesh : NavigationMesh = navmesh
|
|
var navigationmesh : NavigationMesh = navmesh
|
|
NavigationMeshGenerator.bake(navigationmesh, self)
|
|
NavigationMeshGenerator.bake(navigationmesh, self)
|
|
# remove old resource first to trigger a full update
|
|
# remove old resource first to trigger a full update
|
|
navmesh = null
|
|
navmesh = null
|
|
navmesh = navigationmesh
|
|
navmesh = navigationmesh
|
|
-
|
|
|
|
|
|
+
|
|
# or use NavigationServer API to update region with prepared navmesh
|
|
# or use NavigationServer API to update region with prepared navmesh
|
|
var region_rid : RID = get_region_rid()
|
|
var region_rid : RID = get_region_rid()
|
|
NavigationServer3D.region_set_navmesh(region_rid, navmesh)
|
|
NavigationServer3D.region_set_navmesh(region_rid, navmesh)
|
|
@@ -104,15 +104,15 @@ If the navmesh resource is already prepared, the region can be updated with the
|
|
|
|
|
|
.. warning::
|
|
.. warning::
|
|
|
|
|
|
- Property values on a NavigationMesh resource like ``cell_size`` need
|
|
|
|
- to match the actual mesh data stored inside in order to merge
|
|
|
|
|
|
+ Property values on a NavigationMesh resource like ``cell_size`` need
|
|
|
|
+ to match the actual mesh data stored inside in order to merge
|
|
different navigation meshes without issues.
|
|
different navigation meshes without issues.
|
|
|
|
|
|
NavigationRegion2D and Navigation3D both use meshes to mark traversable areas, only the tools to create them are different.
|
|
NavigationRegion2D and Navigation3D both use meshes to mark traversable areas, only the tools to create them are different.
|
|
|
|
|
|
For 2D NavigationPolygon resources are used to draw outline points in the editor. From these outline points the NavigationServer2D creates a mesh to upload navigation data to the NavigationServer.
|
|
For 2D NavigationPolygon resources are used to draw outline points in the editor. From these outline points the NavigationServer2D creates a mesh to upload navigation data to the NavigationServer.
|
|
|
|
|
|
-For 3D NavigationMesh resources are used. Instead of providing draw tools the 3D variant
|
|
|
|
|
|
+For 3D NavigationMesh resources are used. Instead of providing draw tools the 3D variant
|
|
provides an extensive amount of parameters to bake a navigation mesh directly from 3D source geometry.
|
|
provides an extensive amount of parameters to bake a navigation mesh directly from 3D source geometry.
|
|
|
|
|
|
.. note::
|
|
.. note::
|
|
@@ -122,40 +122,40 @@ provides an extensive amount of parameters to bake a navigation mesh directly fr
|
|
2D Navmesh from CollisionPolygons
|
|
2D Navmesh from CollisionPolygons
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
|
|
-The following script parses all child nodes of a NavigationRegion2D for CollisionPolygons
|
|
|
|
-and bakes their shape into the NavigationPolygon. As the NavigationPolygon creates the
|
|
|
|
|
|
+The following script parses all child nodes of a NavigationRegion2D for CollisionPolygons
|
|
|
|
+and bakes their shape into the NavigationPolygon. As the NavigationPolygon creates the
|
|
navigationmesh from outline data the shapes cannot overlap.
|
|
navigationmesh from outline data the shapes cannot overlap.
|
|
|
|
|
|
.. tabs::
|
|
.. tabs::
|
|
.. code-tab:: gdscript GDScript
|
|
.. code-tab:: gdscript GDScript
|
|
|
|
|
|
extends NavigationRegion2D
|
|
extends NavigationRegion2D
|
|
-
|
|
|
|
|
|
+
|
|
var navigationpolygon : NavigationPolygon = get_navigation_polygon()
|
|
var navigationpolygon : NavigationPolygon = get_navigation_polygon()
|
|
-
|
|
|
|
|
|
+
|
|
func _ready():
|
|
func _ready():
|
|
-
|
|
|
|
|
|
+
|
|
parse_2d_collisionshapes(self)
|
|
parse_2d_collisionshapes(self)
|
|
-
|
|
|
|
|
|
+
|
|
navigationpolygon.make_polygons_from_outlines()
|
|
navigationpolygon.make_polygons_from_outlines()
|
|
set_navigation_polygon(navigationpolygon)
|
|
set_navigation_polygon(navigationpolygon)
|
|
-
|
|
|
|
|
|
+
|
|
func parse_2d_collisionshapes(root_node : Node2D):
|
|
func parse_2d_collisionshapes(root_node : Node2D):
|
|
-
|
|
|
|
|
|
+
|
|
for node in root_node.get_children():
|
|
for node in root_node.get_children():
|
|
-
|
|
|
|
|
|
+
|
|
if node.get_child_count() > 0:
|
|
if node.get_child_count() > 0:
|
|
parse_2d_collisionshapes(node)
|
|
parse_2d_collisionshapes(node)
|
|
-
|
|
|
|
|
|
+
|
|
if node is CollisionPolygon2D:
|
|
if node is CollisionPolygon2D:
|
|
-
|
|
|
|
|
|
+
|
|
var new_collision_outline : PackedVector2Array = PackedVector2Array()
|
|
var new_collision_outline : PackedVector2Array = PackedVector2Array()
|
|
var collisionpolygon_transform : Transform2D = node.get_global_transform()
|
|
var collisionpolygon_transform : Transform2D = node.get_global_transform()
|
|
var collisionpolygon : CollisionPolygon2D = node.get_polygon()
|
|
var collisionpolygon : CollisionPolygon2D = node.get_polygon()
|
|
-
|
|
|
|
|
|
+
|
|
for vertex in collisionpolygon:
|
|
for vertex in collisionpolygon:
|
|
new_collision_outline.append(collisionpolygon_transform.xform(vertex))
|
|
new_collision_outline.append(collisionpolygon_transform.xform(vertex))
|
|
-
|
|
|
|
|
|
+
|
|
navigationpolygon.add_outline(new_collision_outline)
|
|
navigationpolygon.add_outline(new_collision_outline)
|
|
|
|
|
|
Procedual 2D Navmesh
|
|
Procedual 2D Navmesh
|
|
@@ -167,7 +167,7 @@ The following script creates a new 2D navigation region and fills it with proced
|
|
.. code-tab:: gdscript GDScript
|
|
.. code-tab:: gdscript GDScript
|
|
|
|
|
|
extends Node2D
|
|
extends Node2D
|
|
-
|
|
|
|
|
|
+
|
|
var new_2d_region_rid : RID = NavigationServer2D.region_create()
|
|
var new_2d_region_rid : RID = NavigationServer2D.region_create()
|
|
|
|
|
|
var default_2d_map_rid : RID = get_world_2d().get_navigation_map()
|
|
var default_2d_map_rid : RID = get_world_2d().get_navigation_map()
|
|
@@ -182,7 +182,7 @@ The following script creates a new 2D navigation region and fills it with proced
|
|
])
|
|
])
|
|
new_navpoly.add_outline(new_outline)
|
|
new_navpoly.add_outline(new_outline)
|
|
new_navpoly.make_polygons_from_outlines()
|
|
new_navpoly.make_polygons_from_outlines()
|
|
-
|
|
|
|
|
|
+
|
|
NavigationServer2D.region_set_navpoly(new_2d_region_rid, new_navpoly)
|
|
NavigationServer2D.region_set_navpoly(new_2d_region_rid, new_navpoly)
|
|
|
|
|
|
Procedual 3D Navmesh
|
|
Procedual 3D Navmesh
|
|
@@ -194,17 +194,17 @@ The following script creates a new 3D navigation region and fills it with proced
|
|
.. code-tab:: gdscript GDScript
|
|
.. code-tab:: gdscript GDScript
|
|
|
|
|
|
extends Node3D
|
|
extends Node3D
|
|
-
|
|
|
|
|
|
+
|
|
var new_3d_region_rid : RID = NavigationServer3D.region_create()
|
|
var new_3d_region_rid : RID = NavigationServer3D.region_create()
|
|
-
|
|
|
|
|
|
+
|
|
var default_3d_map_rid : RID = get_world_3d().get_navigation_map()
|
|
var default_3d_map_rid : RID = get_world_3d().get_navigation_map()
|
|
NavigationServer3D.region_set_map(new_3d_region_rid, default_3d_map_rid)
|
|
NavigationServer3D.region_set_map(new_3d_region_rid, default_3d_map_rid)
|
|
-
|
|
|
|
|
|
+
|
|
var new_navmesh : NavigationMesh = NavigationMesh.new()
|
|
var new_navmesh : NavigationMesh = NavigationMesh.new()
|
|
var new_plane_mesh : PlaneMesh = PlaneMesh.new()
|
|
var new_plane_mesh : PlaneMesh = PlaneMesh.new()
|
|
new_plane_mesh.size = Vector2(10.0, 10.0)
|
|
new_plane_mesh.size = Vector2(10.0, 10.0)
|
|
new_navmesh.create_from_mesh(new_plane_mesh)
|
|
new_navmesh.create_from_mesh(new_plane_mesh)
|
|
-
|
|
|
|
|
|
+
|
|
NavigationServer3D.region_set_navmesh(new_3d_region_rid, new_navmesh)
|
|
NavigationServer3D.region_set_navmesh(new_3d_region_rid, new_navmesh)
|
|
|
|
|
|
Navmesh for 3D GridMaps
|
|
Navmesh for 3D GridMaps
|
|
@@ -216,10 +216,10 @@ The following script creates a new 3D navmesh from the mesh of a GridMap item, c
|
|
.. code-tab:: gdscript GDScript
|
|
.. code-tab:: gdscript GDScript
|
|
|
|
|
|
extends GridMap
|
|
extends GridMap
|
|
-
|
|
|
|
|
|
+
|
|
# enable navmesh for grid items
|
|
# enable navmesh for grid items
|
|
set_bake_navigation(true)
|
|
set_bake_navigation(true)
|
|
-
|
|
|
|
|
|
+
|
|
# get mesh from grid item, bake and set a new navmesh for the library
|
|
# get mesh from grid item, bake and set a new navmesh for the library
|
|
var gridmap_item_list : PackedInt32Array = mesh_library.get_item_list()
|
|
var gridmap_item_list : PackedInt32Array = mesh_library.get_item_list()
|
|
for item in gridmap_item_list:
|
|
for item in gridmap_item_list:
|
|
@@ -228,10 +228,10 @@ The following script creates a new 3D navmesh from the mesh of a GridMap item, c
|
|
navmesh.create_from_mesh(item_mesh)
|
|
navmesh.create_from_mesh(item_mesh)
|
|
mesh_library.set_item_navmesh(item, item_mesh)
|
|
mesh_library.set_item_navmesh(item, item_mesh)
|
|
mesh_library.set_item_navmesh_transform(item, Transform3D())
|
|
mesh_library.set_item_navmesh_transform(item, Transform3D())
|
|
-
|
|
|
|
|
|
+
|
|
# clear the cells
|
|
# clear the cells
|
|
clear()
|
|
clear()
|
|
-
|
|
|
|
|
|
+
|
|
# add procedual cells using the first item
|
|
# add procedual cells using the first item
|
|
var _position : Vector3i = Vector3i(global_transform.origin)
|
|
var _position : Vector3i = Vector3i(global_transform.origin)
|
|
var _item : int = 0
|
|
var _item : int = 0
|