Can I know whether a static destination is ever reachable?

Just started using the A* Pathfinding software! Using version 4.2.10 Pro, RichAI on a recast graph.

My problem is that the RichAI path search never fails, even when it cannot ever get to its destination. Looking at the documentation I understand this is by design? Say for example I put the destination way outside the navmesh area, the RichAI will path to a point that’s as close as it can get to the destination and move there, but “reachedDestination” will of course never be true. Is the idea that I should also check “reachedEndOfPath”?

The real issue for me is that I would like to know before starting to move whether the destination (which is static) is ever reachable. Is this possible?

Hey,

You can use the IsPathPossible utility. https://arongranberg.com/astar/docs/pathutilities.html#IsPathPossible

2 Likes

Thank you - that was helpful. I wasn’t aware of this PathUtilities class.

A related question: How do I determine whether I have gotten as close to the destination as I am going to get?

If the destination is not reachable, “reachedDestination” will never be true. I thought of checking “reachedEndOfPath” but that is true for a few frames when the AI first gets a new destination because it isn’t updated immediately - so it’s still true from the last pathfind; “hasPath && reachedEndOfPath” also returns true for a few frames so I can’t use that.

I’d like something that tells me: “Has the AI received a destination and started moving but can get no closer to the destination”? This seems like such a common use case I’m surprised it’s not built in somehow? Or maybe it is and I just don’t know where?

Hi

You can use ai.pathPending to check if the reachedEndOfPath property is up to date.
Something like !ai.pathPending && ai.reachedEndOfPath.

Alternatively you could request the closest point to the destination that the agent can reach using

NNInfo playerNode = AstarPath.active.GetNearest(ai.position, NNConstraint.Default);
var nn = NNConstraint.Default;
nn.constrainArea = true;
nn.area = playerNode.node.Area;
NNInfo closestNode = AstarPath.active.GetNearest(ai.destination, nn);
Debug.DrawLine(ai.destination, closestNode.position);
1 Like

@aron_granberg Is there a way to use AstarPath.active.GetNearest() as read-only so that it can be used in a job?

Sorry. There is no way to do this safely. (you could send a GCHandle with a reference to the AstarPath object which would allow you to use it in a job, but it wouldn’t be thread safe if any graph updates are happening at the same time).

I can guarantee that no graph updates will happen at the same time because i disabled all auto updates and have full control over when updates occur. The problem is that I can’t use AstarPath.active. When I run my system gives this error:

"error DC0004: Entities.ForEach Lambda expression captures a non-value type ‘activePath’. This is only allowed with .WithoutBurst() and .Run()

It is because activePath is a class, and Burst doesn’t like classes. Is there a low-level function call that doesn’t use classes that I can use instead?

You can trick Unity to get a managed reference inside a job using a GCHandle.

var handle = System.Runtime.InteropServices.GCHandle.Alloc(myManagedObject);
// pass 'handle' to a job and retreive the value with handle.Target.
// Make sure to call handle.Free when the job is done.

However, you will not be able to use it with burst. You can use it in the jobs system, however.

Accessing the graphs from burst would require me to essentially rewrite the whole package to use native arrays and similar data structures for everything. I have been rewriting some parts of it in this way (e.g. the local avoidance system), but rewriting the entire thing and keeping backwards compatibility at the same time is extremely hard without incurring heavy performance losses.