Search Unity

Why does NavMesh.CalculatePath() fail while NavMeshAgent.SetDestination() works?

Discussion in 'Navigation' started by aksik517, Sep 29, 2019.

  1. aksik517

    aksik517

    Joined:
    Oct 22, 2018
    Posts:
    3
    Hi. I just don't get it. All posts I've found mostly says theirs CalculatePath always finds a path even if it shouldn't (usually the answer is it found a partial path). In my case, no matter what I do, NavMesh.CalculatePath() or NavMeshAgent.CalculatePath() always fails. If I use NavMeshAgent.SetDestination() it works and finds a partial path.

    This one works:
    Code (CSharp):
    1. private void Start()
    2.     {
    3.         agent = gameObject.AddComponent<NavMeshAgent>();
    4.         agent.speed = 3.5f;
    5.         agent.radius = 1.69f;
    6.         agent.height = 2.57f;
    7.         if(!agent.SetDestination(Base.First().transform.position))
    8.             Debug.Log("Failed");
    9.         agent.isStopped = true;
    10.     }
    And this one doesn't:
    Code (CSharp):
    1. private void Start()
    2.     {
    3.         agent = gameObject.AddComponent<NavMeshAgent>();
    4.         agent.speed = 3.5f;
    5.         agent.radius = 1.69f;
    6.         agent.height = 2.57f;
    7.         path = new NavMeshPath();
    8.         NavMesh.CalculatePath(transform.position, Base.First().transform.position, NavMesh.AllAreas, path);
    9.         if (path.status == NavMeshPathStatus.PathPartial)
    10.         {
    11.             Debug.Log("Is partial, yey"); // <= never happens
    12.         }
    13.  
    14.         agent.SetPath(path);
    15.         agent.isStopped = true;
    16.     }
    The second one doesn't even have any corners in path.corners. How is that possible?

    The thing is, I only need the path to check how long it is. That's why I need it to calculate immediately.
     
  2. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    Why would you expect only
    NavMeshPathStatus.PathPartial 
    , what about
    NavMeshPathStatus.PathComplete
    ?
     
  3. canis

    canis

    Joined:
    Oct 25, 2013
    Posts:
    79
    if you only want to calculate the path total travel distance, you don't need NavMeshAgent component.
    and... I'm not sure why you can't get the result on 2nd script.
    it's too many possibilities

    may be you can try to run the following script, hope you can find the answer by yourself.
    PS: assign point A & B, near your navmesh. and toggle the script's enable/disable.
    that will draw the result on screen for 10 sec.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.AI;
    3.  
    4. public class NavMeshTest : MonoBehaviour
    5. {
    6.     public Transform PointA = null;
    7.     public Transform PointB = null;
    8.     private void OnEnable()
    9.     {
    10.         if (PointA == null || PointB == null)
    11.             return;
    12.  
    13.         NavMesh.SamplePosition(PointA.position, out NavMeshHit hitA, 10f, NavMesh.AllAreas);
    14.         NavMesh.SamplePosition(PointB.position, out NavMeshHit hitB, 10f, NavMesh.AllAreas);
    15.  
    16.         NavMeshPath path = new NavMeshPath();
    17.         if (NavMesh.CalculatePath(hitA.position, hitB.position, NavMesh.AllAreas, path))
    18.         {
    19.             Debug.DrawLine(hitA.position + Vector3.up, hitB.position + Vector3.up, Color.red, 10f, true); // a red line float in air
    20.             int cnt = path.corners.Length;
    21.            
    22.             float distance = 0f;
    23.             for (int i =0; i<cnt - 1; i++)
    24.             {
    25.                 distance += (path.corners[i] - path.corners[i + 1]).magnitude;
    26.                 Debug.DrawLine(path.corners[i], path.corners[i + 1], Color.green, 10f, true);
    27.             }
    28.             Debug.Log($"Total distance {distance:F2}");
    29.         }
    30.         else
    31.         {
    32.             Debug.LogError("Mission Fail");
    33.         }
    34.     }
    35. }
    36.  
     
  4. aksik517

    aksik517

    Joined:
    Oct 22, 2018
    Posts:
    3
    Well, It could be != PathInvalid, but I'm sure the only path to that object that can be created is partial.
     
  5. aksik517

    aksik517

    Joined:
    Oct 22, 2018
    Posts:
    3
    Thanks for replay, I'll check that probably tommorow.
     
  6. Drake4

    Drake4

    Joined:
    Jun 17, 2022
    Posts:
    30
    Guys,

    I like to add my issue with this. Based on the manual its declared like this:

    Code (CSharp):
    1. public bool CalculatePath(Vector3 targetPosition, AI.NavMeshPath path);
    So you can include this directly in your if condition.

    Now my problem is this returns false for some agents (but not for all) even if there is clearly a path given.
    i. e. I make the agent run to target position (player) than return to start position, on a specific trigger it should return to the player. When the trigger hits I check for the path and CalculatePath returns false despite the player not moving.
    The agents differ in size, and speed and use different NavMeshes for that reason. But since the problem agent can manoever the whole distance before it returns it can't be an issue with the Mesh.

    Any insight is welcome.
     
  7. NilsS

    NilsS

    Joined:
    Sep 12, 2014
    Posts:
    5
    Same issue here:

    Code (CSharp):
    1.  
    2. var path = new NavMeshPath();
    3. var pathSuccess = _agent.CalculatePath(pos, path); // false
    4. var destSuccess = _agent.SetDestination(pos);      // true
    5.  
    I've searched the forums & internet the whole afternoon, to no avail. Only thing I found is people with the very same problem and without any reply from Unity officials. Sad..
     
  8. Saniell

    Saniell

    Joined:
    Oct 24, 2015
    Posts:
    195
    SetDestination returns whether path was successfully requested, which means agent doesn't know yet if there's actually a path there, it just can map your point to some nearest point on navmesh. Contrary to that, CalculatePath does all of pathfinding and returns if it could find path at all
     
    YagirX likes this.