I’m new to Godot and currently struggling with a NavigationAgent2D and multi-layer TileMap & TileSet issue in my game. The TileMap has two layers: ground and trees.
TileSet Layers: My TileSet includes a navigation layer for all ground tiles and a physics layer for the tree tiles. The trees are set with a physics layer in the TileSet editor, causing collisions with players and enemies correctly.
The Issue: Enemies, using NavigationAgent2D, don’t navigate around the trees; they aim straight through them. This is evident as the navigation path is displayed for debugging in real-time.
A Specific Observation: When I place the tree tiles on the ground layer of the TileMap, the navigation agent successfully finds a way around them. However, this leads to a visual issue where the trees look somewhat broken due to the transparent background showing the default background
My Confusion: I assumed that defining a navigation layer and a physics layer for trees would guide NavigationAgent2D about passable and impassable tiles, no matter what TileMap layer the tiles are on. It’s puzzling why the agent fails to avoid trees on a separate layer but works when they’re on the first layer of the TileMap
I’m unsure what I’m missing in this setup, and why the navigation agent behaves differently based on the layer placement. Any insights, suggestions, or advice, especially from a beginner’s viewpoint, would be immensely helpful.
I assume you are baking the navigation mesh with e.g. a NavigationRegion2D or the NavigationServer2D. What counts for the pathfinding is the navigation mesh so naturally all physics collision is ignored if it is not somehow baked into a navigation mesh surface.
The 2D navigation mesh baking only parses TileMapLayer0. It parses only the Layer0 because navigation meshes can not overlap or intersect. TileMap has not figured out how it can prepare its internals to avoid broken navigation meshes caused by TileMapLayers so that feature is unsupported.
What some users do to work around this is to use a TileMap to mirror just the cells with navigation polygon and collision polygons for the baking. Or some add the polygons manually in scripts and bake the SourceGeometry with the NavigationServer2D.
Thank you so much for your detailed explanation. It really helped clarify things for me, especially regarding the limitations of parsing only TileMapLayer0 for navigation mesh baking in Godot. Your insight into this matter is greatly appreciated!
I must admit, I’m not fully versed in how the navigation mesh is being baked. I haven’t been using NavigationRegion2D or NavigationServer2D explicitly. My approach was based on a tutorial I followed on YouTube (link to the tutorial), where I added NavigationAgent2D to the enemy. In the tileset, I only added one layer of navigation and one layer of physics. Specifically, I applied the physics layer to the tree tiles and the navigation layer to the ground tiles.
Given your explanation about the parsing of only layer0, I’m now wondering how I could correctly build the navigation mesh via the tilemap. My main challenge is integrating my trees on layer0 without disrupting the visuals, particularly due to the transparency issue I encounter when adding tiles with transparency on layer 0.
Do you have any suggestions or tips on how I might approach this? Is there a way to work around the transparency issue when adding my tree tiles to layer0, so that they can be part of the navigation mesh without affecting the game’s visual appeal?
Again, thank you for your valuable input, and I look forward to any further advice you can provide!
As mentioned some users solve this by using 2 TileMaps. One for the visuals and one they mirror with scripts with cells that have just the logical data like navmesh and collision polygons that they use for the baking.
I know this is a bit old at this point, but since I’ve ran into a similar issue and haven’t found a clear answer in the forums, and while the suggested solution is one option, I decided to add some other alternatives as well.
As it’s been mentioned, the navigation polygons in different TileMapLayer instances (and in different layers of TileMap) are merged which means if there’s a navigation tile in one tile map layer, it doesn’t matter if another layer doesn’t have it, in the final navigation polygon, that tile will be considered traversable by the navigation agent. Another important point, also mentioned already is that physics layer doesn’t affect the navigation at all, which means that making tile collidable doesn’t automatically makes it not traversable by the navigation agents.
So, for OP’s specific case, one option would be to add an alternative ground tile that looks the same, but doesn’t have navigation on it and use that one in those places where trees will be placed on top.
Another option would be to not have tiles in the ground layer where there are trees in the tree layer. Although this assumes that the trees don’t need to be blended with the ground in the background (in which case you don’t really need two layers anyway).
Finally, there’s a third option of resolving this with a script. It basically comes down to checking other layers and eliminating navigation tiles when there’s an untraversable tile in any of the layers at the same coordinates. This video explains it nicely: https://youtu.be/7ZAF_fn3VOc?t=530 .
I hope this is helpful the next person with the same issue.