A* Pathfinding Project

Unexpected results from AstarPath.active.GetNearest with disabled Node Links


#1

TLDR: It seems that disabled Node Links are getting returned as PointGraph positions from AstarPath.active.GetNearest(). Or possibly, after enabling and then later disabling a Node Link, then PointGraph continues to think its endpoints are valid mesh positions.

I’ve been starting to add some advanced features to my map, which includes breakable floors. Basically, the floor is a normal part of the navmesh initially, but as soon as someone walks on it, it breaks and falls, leaving a gap in the navmesh. At that time, I enable some Node Links that can be used to cross the gap. Here’s an example of what one of those breakable platforms looks like:

This generally works well. When the break occurs, I activate the NavMeshCut you can see in the screenshot, and I conditionally activate the two Node Links you can see. The tricky thing is that I want this to be fairly dynamic, so I include node links that span both directions. But on break, I only activate the node links whose Start and End positions are sufficiently close to the NavMesh. I’m using AstarPath.active.GetNearest() to get the closest position on the navmesh to determine whether the Start and End positions are close to the next mesh:

var positionOnMesh = AstarPath.active.GetNearest(position, NNConstraint.Default);
var isClose = (positionOnMesh.position - position).sqrMagnitude < 0.05f;

After enabling/disable the Node Link based on this, I then update the graph:

Bounds bounds = graphUpdateCollider.bounds;
var guo = new GraphUpdateObject(bounds);

// Set some settings
guo.updatePhysics = true;
AstarPath.active.UpdateGraphs(guo);

This works great the first time I do this. I end up with a valid Node Link spanning the gap, and the node link hanging out in air doesn’t get added.

The problem comes when I run this same code again to reevaluate the links. The second time I run AstarPath.active.GetNearest(), it will return me PointGraph nodes matching the positions of the disabled Node Links. So the second time I run this code, all of the Node Links think they’re valid, because all of the Node Links think they’re near the Nav Mesh. The result is that agents are trying to go to those endpoints, even though they’re in the middle of the air.

I’ve worked around this by passing a constraint to GetNearest, querying only the Recast graph, not the Point graph. But I worry that other stuff is going to go wrong because I have these invalid points in my Point graph now. Once a Node Link is activated, are its positions permanantly part of the graph? Do I need to do something special to remove a node link from the graph other than merely disabling it and recalculating the mesh?