Closed ThePat02 closed 1 year ago
The 2D navigation mesh baking parses only the TileMap Layer0. This is not a bug but an intentional limitation.
The TileMap Layers system does not work for the navigation mesh system. You can not overlap navigation meshes from different TileMap Layers all in the same navigation map like you can do with visuals or collision. Overlapping navigation meshes causes the edge sync to implode breaking the navigation map and therefor the pathfinding.
So this is not a matter of the 2D navigation mesh baking supporting the TileMap, which it already does, but a matter of the TileMap figuring out its internals and features and how they can work correctly with the used engine features.
One solution could be that the TileMap adds options to define what Layers should be combined and how, making sure that there is only a single combined "layer" in the end prepared for the parser for the navigation mesh baking.
How would you suggest solving this issue in a project? Havin a dedicated layer on your tilemap where you only put collision tiles?
While this is not a provided feature of the TileMap users can work around the issue by using a NavigationMeshSourceGeometry2D
object to parse the TileMap Layer0 with NavigationServer2D.parse_source_geometry_data()
.
The objects from the other TileMap Layers can be added on top manually to the source geometry for the baking. E.g. collision shapes from other TileMap Layers can be added as obstruction outlines to the source geometry while navigation polygons can be added as traversable outlines.
With the source geometry prepared the navigation mesh can be baked with NavigationServer2D.bake_from_source_geometry_async()
.
If adding this manually in script is too problematic another option might be to use a secondary TileMap as a "replacement layer" and a secondary source geometry. Parse Layer0 as well, then combine the data from the two source geometries into one for the baking. Or place the two TileMaps in a way that the parsing can read both into the same source geometry. The problem with many TileMap nodes will be that the parsing will run on the main thread because they are nodes in the SceneTree.
Or place the two TileMaps in a way that the parsing can read both into the same source geometry. The problem with many TileMap nodes will be that the parsing will run on the main thread because they are nodes in the SceneTree.
I just use two TileMap nodes for now. This is a quick and dirty solution for now.
Hey! I made a small tool called TileMapsChef (GitHub) following @smix8's suggestions. Maybe in the future I'll make it a bit more user-friendly (layer selection, proper UI). But if you just want to bake all colliders from all layers into your NavigationRegion2D, it will do the job.
Godot version
v4.2-beta3
System information
Godot v4.2.beta3 - Windows 10.0.22621 - Vulkan (Forward+) - integrated AMD Radeon(TM) Graphics (Advanced Micro Devices, Inc.; 30.0.13044.14002) - AMD Ryzen 9 5900HX with Radeon Graphics (16 Threads)
Issue description
When baking a
NavigationPolygon
in aNavigationArea2D
, only the collision data of the first layer of aTileMap
is used. For example: Tiles placed on the second layer that have collision will not be taken into account when baking. If you change the order of the layers, the same bug appears and only the first layer will be baked into theNavigationPolygon
!Steps to reproduce
NavigationArea2D
and add a newNavigationPolygon
.TileMap
as a child and fill different layers with objects that have collision data.NavigationPolygon
.Minimal reproduction project
minimal_reproduction_navigationbaking.zip