GetNearest returns undesired result

Hi there,

I have the following check in place to decide whether an enemy can reach the player or not:

        NNConstraint constraint = new NNConstraint();
        constraint.graphMask = 1; // Navigation Graph

        GraphNode node1 = AstarPath.active.GetNearest(transform.position, constraint).node;
        GraphNode node2 = AstarPath.active.GetNearest(destination, constraint).node;

        return PathUtilities.IsPathPossible(node1, node2);

This doesn’t work well in some scenarios, like the one below. The player stands on top of a barrier, which itself is narrow enough to not have any walkable area on it.

GetNearest() returns the same node both for the enemy on the ground, and the player on top of the barrier. The enemy therefore decides “yes, I can get to the player”, which isn’t what we want.

Is the best solution to this to adjust AstarPath.maxNearestNodeDistance?

I start to think posting in this forum is an excellent way to sort my thoughts and come to a solution :slight_smile:

I’m now doing the following: I query the closest node to the player, and check how far away the actual players transform is from the closest point on that node.

If it’s more than a certain distance, I regard the player as off the grid and unreachable. I therefore don’t need to check IsPathPossible anymore.

I added below code to my players Movement script. The _playerIsNearNavigationGraph is a nullable boolean that is reset to 0 in the beginning of the Update method, IF the player is grounded.

So in other words:

  • If noone asks the player “are you on the grid?”, no code is run at all.

  • If someone asks the player “are you on the grid?”, the code runs 1x per frame, no matter how many times the player is queried

  • If someone asks the player “are you on the grid” while he’s jumping around the place, the last known value is returned. I don’t want attackers to stop chasing me when I’m in the air.

      public bool PlayerIsNearNavigationGraph()
      {
          if (!_playerIsNearNavigationGraph.HasValue)
          {
              NNConstraint constraint = new NNConstraint();
              constraint.graphMask = 1; // Navigation Graph
    
              GraphNode node = AstarPath.active.GetNearest(transform.position, constraint).node;
    
              // Check max distance of node vs current destination
              Vector3 closestPoint = node.ClosestPointOnNode(transform.position);
              float distance = Vector3.Distance(closestPoint, transform.position);
              _playerIsNearNavigationGraph = (distance < 1.5f);
          }
    
          return _playerIsNearNavigationGraph.Value;
      }
1 Like