Mesh not baked properly for NavigationServer2D

Godot Version

4.2

Question

Hello,

I am trying to update a NavigationPolygon on runtime, when adding a new building on scene. Building is a separate node with sprite, collision shapes and collision polygon as well.

The interesting thing is that code works perfectly if the building exists on scene before runtime, so I will add it manually on scene, then make a test run, then make a baking - it will work just fine, it will be detected by code and my NavigationAgent will avoid it as obstacle. But if I will instantiate a building during runtime - it won’t be visible for my NavAgent.

Here is the code I have:

This is my navigation region code:

extends NavigationRegion2D

@onready var nav_server = $"../NavigationServer"
var new_navigation_polygon : NavigationPolygon = get_navigation_polygon()

# Called when the node enters the scene tree for the first time.
func _ready():
	parse_2d_collisionshapes(self)
	new_navigation_polygon.make_polygons_from_outlines()
	set_navigation_polygon(new_navigation_polygon)

# Called every frame. 'delta' is the elapsed time since the previous frame.

func bakeall():
	parse_2d_collisionshapes(self)
	new_navigation_polygon.make_polygons_from_outlines()
	set_navigation_polygon(new_navigation_polygon)
	nav_server.update_navserver(new_navigation_polygon)
	
func _process(delta):
	pass

func update_map(object):
	object.get_parent().remove_child(object)
	add_child(object)
	print('object added as a child')
	print('start new baking')
	bakeall()
	print('baking finished')

func parse_2d_collisionshapes(root_node: Node2D):
	for node in root_node.get_children():
		if node.get_child_count() > 0:
			parse_2d_collisionshapes(node)
		if node is CollisionPolygon2D:
			print('Collision polygon found: ', node)
			var collisionpolygon_transform: Transform2D = node.get_global_transform()
			var collisionpolygon: PackedVector2Array = node.polygon
			var new_collision_outline: PackedVector2Array = collisionpolygon_transform * collisionpolygon
			new_navigation_polygon.add_outline(new_collision_outline)
			print(new_collision_outline)

So basically it goes through all own child and makes a navigation polygon out of that. This is my setup I have before making a run:

image

And it works absolutely perfect - my navagent considers both staticbodies as a obstacles and avoids them when they are on it’s path.

But then, if I will instantiate an object during runtime, I will call a bakeall() function - as far as I understand it kinda overwrites the navigation polygon and ‘bakes’ it again.

And then I have everything stored in NavigationServer2D script:

extends Node

var speed = 100
var path = []
var map
var region
@onready var NavReg = $"../NavigationRegion2D"

func _ready():
	setup_navserver()

func setup_navserver():
	#Create a new navigation map
	map = NavigationServer2D.map_create()
	NavigationServer2D.map_set_active(map, true)
	
	#Create a new navigation region and add it to the map
	region = NavigationServer2D.region_create()
	NavigationServer2D.region_set_transform(region, Transform2D())
	NavigationServer2D.region_set_map(region, map)

	#Set navgiation mesh for the region
	var navigation_poly = NavigationMesh.new()
	navigation_poly = NavReg.navigation_polygon
	NavigationServer2D.region_set_navigation_polygon(region, navigation_poly)
	print('Server setup finished.')
	
func get_navigation_values(start_position, end_position):
	path = NavigationServer2D.map_get_path(map, start_position, end_position, true)
	return[path, true]


func update_navserver(new_poly):
	NavigationServer2D.region_set_transform(region, Transform2D())
	NavigationServer2D.region_set_navigation_polygon(region, new_poly)

In my understanding, whenever I put a new object and call Bakeall() function it should work fine and new obstacle should be visible to a NavAgent in the end. But it doesn’t happen - only objects that were on scene before runtime are obstacles. Even though they are similar (exactly the same) as I am instantiating.

Here is the navigation agent code:

extends CharacterBody2D

@onready var NavReg = $"../NavigationRegion2D"
@onready var nav = get_node("NavigationAgent2D")
@onready var navServer = get_node("../NavigationServer")

var speed = 100
var path = []
var map
	
func _physics_process(delta):
	var walk_distance = 100 * delta
	move_along_path(walk_distance)
	
func move_along_path(distance):
	var last_point = self.position
	while path.size():
		var distance_between_points = last_point.distance_to(path[0])
		if distance <= distance_between_points:
			self.position = last_point.lerp(path[0], distance / distance_between_points)
			return
		distance -= distance_between_points
		last_point = path[0]
		path.remove_at(0)
		
	self.position = last_point
	set_process(false)
	
func _update_navigation_path(generated_path, value):
	path = generated_path
	path.remove_at(0)
	set_process(value)
func _unhandled_input(event):
	if not event.is_action_pressed("click"):
		return
	else:
		var new_path = navServer.get_navigation_values(self.position, get_global_mouse_position())[0]
		var new_value = navServer.get_navigation_values(self.position, get_global_mouse_position())[1]
		_update_navigation_path(new_path, new_value)

I have a feeling that I’m missing something very obvious, but I can’t find it. Any help would be appreciated, thanks a lot in advance!