Is there a way to check if my agent can reach it's destination?

  • A* version: [5.3.4]
  • Unity version: [2023.3.42f]

Hey there!

Been using a* on my first person 3d project, so far it’s been great. I have a question: is there a simple way to check if my agent’s graph can actually reach it’s destination? (for example, I would like my NPCs to act differently if theyr destinatino is ona different floor).

I did try using IsPathPossible but as for now it’s always returns false even when the NPC clearly has direct path towards the target, so I’m probably unfamiliar with something. Here’s an example for what I’ve been trying to do:

    var startNode = AstarPath.active.GetNearest(transform.position).node;

    var endNode = AstarPath.active.GetNearest(newDestination.transform.position).node;

    // Check if a path is possible on the graph

    if (PathUtilities.IsPathPossible(startNode, endNode))

    {

        followerEntity.canMove = true;

    }

Daniel

Hi

That code looks correct.

I’d check if you get the nodes you expect, using e.g.

Debug.DrawRay((Vector3)endNode.position, Vector3.up, Color.red);

I’m still struggling to get this right. The debug looks like the nodes are in the correct places (there’s a very clear walkable path between them), but still it returns false 99% of the time (sometime it would start walking and stop in the middle). When I manually drag the object around with my mouse, sometimes the agent will find it, return true, and go to the destination—but these situations are very hard to reproduce, and I can’t find the logic behind it.

I’m wondering if there’s a mismatch between the transform.position and the node I’m turning it into? I’ve tried to add constraints, but it’s still not working. Maybe there’s a specific constraint that I should be using in order to make sure the nodes are indeed positioned correctly on the graph? Right now I’m trying this, but it’s still no go:

public void MoveTowardsDestination(GameObject newDestination)
{
followerEntity.destination = newDestination.transform.position; 
NNConstraint constraint = NNConstraint.Walkable;
var startNode = AstarPath.active.GetNearest(transform.position, constraint).node; 

var endNode = AstarPath.active.GetNearest(newDestination.transform.position, constraint).node; 

if (startNode == null || endNode == null) 

{ 

    Debug.LogError($"{gameObject.name}: Could not find valid path nodes."); 

    followerEntity.canMove = false; 

    return; 

} 

float distanceToTarget = Vector3.Distance(transform.position, newDestination.transform.position); 

float closeEnoughThreshold = 2f; 

if (PathUtilities.IsPathPossible(startNode, endNode) || distanceToTarget <= closeEnoughThreshold) 

{ 

    followerEntity.canMove = true; 

    Debug.Log($"{gameObject.name}: Moving to destination. Distance: {distanceToTarget:F2}m | StartArea: {startNode.Area}, EndArea: {endNode.Area}"); 

} 

else 

{ 

    followerEntity.canMove = false; 

    Debug.LogWarning($"{gameObject.name}: Cannot reach destination. Distance: {distanceToTarget:F2}m | StartArea: {startNode.Area}, EndArea: {endNode.Area}"); 

} 
}

Do you have multiple overlapping graphs in the scene by any chance?

Yes, I have two: for large and small objects. I removed one and it tottaly works! Thanks!

Is there a way to use this logic without removing one of them, though?

Yes, you’ll have to specify which graph to use.

In the latest version:

var constraint = NearestNodeConstraint.Walkable;
constraint.graphMask = GraphMask.FromGraphIndex(0); // For example
var startNode = AstarPath.active.GetNearest(transform.position, constraint).node; 

or in your older version

var constraint = NNConstraint.Walkable;
constraint.nnConstraint.graphMask = GraphMask.FromGraphIndex(0); // For example
var startNode = AstarPath.active.GetNearest(transform.position, constraint).node; 

See also GraphMask - A* Pathfinding Project

You can also get this info from the FollowerEntity:

var constraint = followerEntity.pathfindingSettings.ToNearestNodeConstraint();

IIRC this only works in 5.4+, though.

Thank you so much! I apreciate your time, A* is awesome :slight_smile:

1 Like