Is there a way to extract Navigation Regions (NavigationRegion2D) from a TileMapLayer that has Navigation Layers set?
I’d like to be able to use NavigationServer2D and NavigationRegion2D with using enter cost and travel cost.
Do you also know a good tutorial for NavigationServer2D, adding maps, regions, polygons and baking at runtime. I couldn’t find anything advanced enough.
What do you want to do? The NavigationServer2D is already aware about the TileMapLayer navigation.
If you need full control over the navigation regions I think your only option is to disable navigation in the TileMapLayer and manage the regions manually. You can access the NavigationPolygons of the tiles using TileData.get_navigation_polygon() You can get the TileData of a cell with TileMapLayer.get_cell_tile_data()
That what I’m also trying to figure out.
I spent whole weekend on this, including checking the documentation you sent.
Here is what I’ve been doing so far:
I have a tilemaplayer for ground (grass or sand) , water etc..
I also have another tilemaplayer that is only for pathes.
And another one for resources or other things (like a tree etc)
I use Node2D scenes for buildings. They are not part of any tilemaplayer. But they are placed within grid.
And I have NPCs moving around.
Right now, I’m using AStarGrid2D for pathfinding of the NPCs. I add a weight_scale depending on what that tile is (low to high order → path, grass, sand, water, building(solid point))
It works pretty well with this configuration.
I started experimenting with gridless placement. Especially with the buildings and paths. I’d like to have the user to be able to add different size of pathes and add buildings in a freeform manner. But I still want to keep the core map tiles within grid like ground,sand, water etc. Because that wouldn’t add an extra good gameplay feature to the game in my opinion.
The pathfinding for the NPCs becomes tricky here. I thought maybe I could still use tilemaplayer’s Navigation features. But it seems very hard and maybe not practical to do that. I especially need to be able to access regions to change weights (enter-travel costs).
I don’t think TileMapLayer gives that option natively. I can access them through the NavigationMap but in order to understand which region is which type (like grass, sand, water, path etc..) I need to assign them in specific tilemaplayers and maps, then extract them and do a check…
That kinda works ok for initialization, but then it becomes too hard to figure out during runtime, when user wants to add or remove new paths or buildings. Here I assigned different weighted routes (path, grass etc) to different navigationlayers. So I can figure out which region is which.
func update_weights():
await get_tree().process_frame
var regions : Array[RID] = NavigationServer2D.map_get_regions(get_world_2d().get_navigation_map())
for region in regions:
var layer : int = NavigationServer2D.region_get_navigation_layers(region)
if layer == 0b1:
NavigationServer2D.region_set_travel_cost(region,100)
elif layer == 0b10:
NavigationServer2D.region_set_travel_cost(region,50)
elif layer == 0b100:
NavigationServer2D.region_set_travel_cost(region,0.01)
So I’m thinking of pausing this idea and going with a different one. But if anyone has a possible solution, please let me know.
If anyone is interesed with my other ‘idea’, My tilemap cell size is 128x128. I’m thinking of changing Path TileMapLayer cell size to 16x16 and keeping other cell size as 128x128 for grass, sand, water etc. I’ll still place the builgins in a freeform manner. And the pathes will be placed in 16x16 tilemaplayer. And I’ll still use AStarGrid2D for pathfinding but for 16x16 cell size. This may give me enough flexibility.