Navigation Chunk Demo Update in Runtime

Godot Version

4.3

Question

I’m working with the navigation mesh chunk 2D demo and I’m trying to get the navigation mesh to update in runtime. I think I’m missing something because I feel like it should be as simple as adding a collision polygon to the parse root and reparsing and rebaking. Is there a way to either use procedural nav mesh building or just parsing to get real time cutting up of the nav mesh? I think it would be slow to constantly be reparsing but I’m just trying to get something to cut into the nav mesh during runtime. I’m working on an RTS game and I want to block cells when a unit arrives at their cell. So I thought I could procedurally build/update the nav mesh. But I’m not super clear on how to do that either. I’ve read through the nav mesh docs and I get that you just add a polygon to the nav mesh and there you go but I want that cutting the nav mesh up functionality that the chunk parsing demo does well.

1 Like

Did you happen to figure this out? I’m also trying to understand how to do this.

Yes I did. I still need to look into the chunks more but I got it working for a single navigation mesh. What I ended up doing was:

  1. Create a new NavigationPolygon, NavigationMeshSourceGeometryData2D, and Region in ready.
  2. Set a callback for the parsing and baking.
  3. Enable the region and set it to the default map.
  4. call_deferred NavigationServer2D.parse_source_geometry_data()
  5. On parsing done I add a traversable outline (I just did 1920x1080 for now)
  6. Call NavigationServer2D.bake_from_source_geometry_data_async(…)
  7. On baking done I update the region with the updated nav mesh using NavigationServer2D.region_set_navigation_polygon(region_rid, navigation_mesh)
  8. In my Unit scripts I call a func I made called _bake_obstacle(…)
  9. This will add the calling node to a dictionary which holds node to polygon. Just for keeping track of updates. I update the polygons in the dictionary and then call source_geometry.set_obstruction_outlines(_node_to_obstruction_dict.values()) to update all the obstructions to my dictionary’s current state.
  10. The way I’m using the obstruction outline’s is as static obstacles so I remove them when the unit is moving around. Using NavigationObstacles — Godot Engine (stable) documentation in English
func _bake_obstacle(bake_queue_item):
	# doesn't use agent radius for affecting nav mesh
	#var obstacle_carve: bool = true
	#source_geometry.add_projected_obstruction(obstacle_outline, obstacle_carve)
	
	# shift the polygon's points by its global position
	var temp_polygon_outline = bake_queue_item.polygon.polygon
	for i in range(temp_polygon_outline.size()):
		temp_polygon_outline[i] += bake_queue_item.polygon.global_position
	
	if !_node_to_obstruction_dict.has(bake_queue_item.node):
		source_geometry.add_obstruction_outline(temp_polygon_outline)
	
	# update the polygon that we have for that node in the dict
	_node_to_obstruction_dict[bake_queue_item.node] = temp_polygon_outline
	source_geometry.set_obstruction_outlines(_node_to_obstruction_dict.values())
	
	# Bake the navigation mesh on a thread with the source geometry data.
	NavigationServer2D.bake_from_source_geometry_data_async(
		navigation_mesh,
		source_geometry,
		callback_baking
	)

BakeQueueItem is just a class I made to easily pass required thing between the script handling the baking and my unit scripts.

class BakeQueueItem:
	var node
	var polygon : Polygon2D
	var callable : Callable
2 Likes

Wow thanks for the detailed answer. I’ll try this out, cheers :+1:

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.