When I use NavigationServer2D.bake_from_source_geometry_data_async the mesh appears on screen (I have navigation selected in the debug menu), but the agent won’t find a path. When I use NavigationRegion2D.bake_navigation_polygon() the path appears and the agent can find the path. From my reading these should both work, or at least if NavigationServer2D.bake_from_source_geometry_data_async didn’t work I wouldn’t expect it to show the debug navigation mesh.
I’m just trying to figure out why these are different and if there are docs about how they’re different or why I might be seeing this behavior.
I set up a quick example project to demonstrate what I’m seeing: https://github.com/ToxicGLaDOS/minimal_navigation_reproduction. Make sure to enable visible navigation in Debug > Visible Navigation. Press 1 to bake with NavigationRegion2D.bake_navigation_polygon, and press 2 to bake with NavigationServer2D.bake_from_source_geometry_data_async.
Additionally, clicking the bake button on the NavigationRegion2D node also works as expected.
Interestingly, baking with NavigationRegion2D.bake_navigation_polygon and then baking with NavigationServer2D.bake_from_source_geometry_data_async afterward maintains correct functionality.
A NavigationRegion node is a functionality bundle that does a lot of unasked stuff automatically for users. E.g. setting the changed navigation mesh after the bake on both the node and the server region as an update.
When you parse and bake navigation mesh with the NavigationServer functions you do exactly only that, and not a single step extra. So in this case you need to both manually update your node or server region (if you update the node it will update the server region).
The 2D debug uses canvas draw which is deferred, so if something else triggers it it will draw with the updated navigation mesh data in the end so you see your server baked region update even if that specific update did not trigger the debug draw.
I’m not sure I understand what you mean by “update your node or server region”. Is there a specific function I call to do that, or just make any change like
i found that line to be funny, because it needs to reassign with new one which is by itself after the baking is done to make it work
actually you can read how to use the NavigationServer2D.bake_from_source_geometry_data_async
from here, but you soon will realize it’s meant to be used with RID and not from created NavigationRegion2D node. so it’s fully NavigationServer2D side
a no-op? At best it makes the node perform an update (and maybe that is the key?)
In the docs you linked they use NavigationServer2D.region_set_navigation_polygon(region_rid, navigation_mesh) which makes more sense because navigation_mesh isn’t already linked to a region. But I would think that in my example nav_region.navigation_polygon is already linked to nav_region and updates to the navigation_polygon would be reflected immediately.
My understanding is that bake_from_source_geometry_data updates the NavigationPolygon that you pass in. So if I pass in nav_region.navigation_polygon, I would expect that to update the mesh without a need to call NavigationServer2D.region_set_navigation_polygon or nav_region.navigation_polygon = .... This kind of feels like a pass-by-value vs. pass-by-reference thing, is that what I’m not getting?
this above line actually trying to set the navigation_polygon again, which trigger the NavigationServer2D’s region_set_navigation_polygon method
which is also what the documentation have done after baking:
Huh… I would have thought that setting the navigation_polygon of a NavigationRegion2D in the editor would set the region of the NavigationRegion2D to the navigation_polygon (as if you’d called region_set_navigation_polygon), but maybe that’s not true?
Because if it were already set up then we’d be calling NavigationServer2D::get_singleton(...)->region_set_navigation_polygon with the polygon that’s already set for that region right?
it’s not, because this NavigationServer2D.bake_from_source_geometry_data_async is creating/baking new mesh, and you want it to update to the navigation region2d you already have after it done baking
But we pass nav_region.navigation_polygon to NavigationServer2D.bake_from_source_geometry_data_async. So any updates to it should be reflected immediately. I’m not familiar with the Godot codebase, but I found this:
which to me says that we pass in the navigation polygon by reference and set the vertices on it. Because it’s a Ref<> I would expect that to be visible to the NavigationRegion2D as soon as the vertices are set. No need for any updating, because we aren’t creating a new NavigationPolygon object, we’re just updating the one we passed in as nav_region.navigation_polygon. There must be something I’m missing here, but I just can’t seem to figure it out
I was assuming that the Ref<> template type was implemented similarly to a smart_pointer. We’re passing a Ref<NavigationPolygon> by value for sure, but the underlying NavigationPolygon is the same because it’s wrapped in the Ref. I can’t seem to find the implementation of the Ref class, so that’s just an assumption. But if that’s not the case then how do we get the value back out? Typically if you pass by value I’d expect a return value so we can access the new object, but here we return void, so there has to be something going on behind that Ref<>.
I don’t see anything that stores the mesh once you call NavigationServer2D.bake_from_source_geometry_data_async. Seems to me, all the operations are on the passed in NavigationPolygon