Search Unity

  1. Unity 2019.4 has been released.
    Dismiss Notice
  2. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  3. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

How to use NavMesh.CalculatePath() correctly

Discussion in 'Navigation' started by nostalgicbear, Apr 4, 2015.

  1. nostalgicbear


    Mar 21, 2013
    Hi guys,
    I would really appreciate any help on this topic.

    I have a function that lets my AI choose a random point on a navmesh, The AI then goes there via the "agent.SetDestination" statement. But I dont want an agent to go there unless the path to that point is valid. Can someone please show me how to use the CalculatePath() function correctly to only tell the AI to go there if the path is valid?

    Here is my attempt. I have a state machine for my AI and in the WALKING state, I call this function to get the destination to walk to.

    Code (CSharp):
    1. /*
    2.      * Choose a random point on the navmesh and set that point as your destination
    3.      */
    4.     void ChooseWaypoint()
    5.     {
    6.         float walkRadius = 300; //Radius in which to pick a point
    7.         Vector3 randomDirection = Random.insideUnitSphere * walkRadius;
    8.         randomDirection += transform.position;
    9.         NavMeshHit hit;
    10.         NavMesh.SamplePosition(randomDirection, out hit, walkRadius, 1);
    11.         Vector3 finalPosition = hit.position;
    13.         NavMeshPath path = new NavMeshPath ();
    14.          if (NavMesh.CalculatePath (transform.position, finalPosition, NavMesh.AllAreas, path)) {
    15.             Debug.Log ("Valid path has been found");
    16.             destination = finalPosition;
    17.         } else {
    18.             Debug.Log("No path to that position, picking a new point");
    19.             ChooseWaypoint();
    20.         }
    22.     }

    So if it finds a valid path, in my Update() I set "agent.SetDestination(destination)" The problem I am getting is that it never ever seems to return false when it checks the path, even when a valid path doesnt get found. I check the scene view and can see that my AI sometimes tries to access a part of the map that doesnt have a path to it
    Last edited: Apr 4, 2015
  2. nostalgicbear


    Mar 21, 2013
    Sorry to bump, but I really need this fixed. The work around I have to use is to just get the AI to choose a new destination if they end up stuck, but Id much rather be able to use CalculatePath(). Any help would be great
  3. Smithy43


    Sep 8, 2012
    Try checking the resultant NavMeshPath.status, it might be returning a partial path. i.e. check to see if path.status == NavMeshPathStatus.PathComplete.

    Does that solve your problem?
    hopetolive and laurentlavigne like this.
  4. Baste


    Jan 24, 2013
    Yeah, the status will be set to PathPartial if your agent can only get a part of the way. I think CalculatePath only returns false if the path is invalid - ie. the agent can't move at all.
  5. AmazingRuss


    May 25, 2008
    Same problem... all this time later. NavmeshAgent.SetPath from the same place works fine.
  6. irantutors


    May 16, 2018
    this thread is for 2015
    but maybe you have the same problem .
    1 . check Carve checkbox on navmeshObstacle
    2. and try to use this
    Code (CSharp):
    1.         NavMeshPath path = new NavMeshPath();
    2.         if (NavMesh.CalculatePath(transform.position, _target, NavMesh.AllAreas, path))
    3.         {
    4.             bool isvalid = true;
    5.             if (path.status != NavMeshPathStatus.PathComplete) isvalid = false;
    6.             if (isvalid)
    7.             {
    8.                 anim.SetBool(name, true);
    9.                 navMesh.SetDestination(_target);
    10.                 navMesh.isStopped = false;
    11.                 isActive = true;
    12.             }
    13.             else
    14.             {
    15.                 navMesh.isStopped = true;
    16.                 isActive = false;
    17.                 StopAnimation("walk");
    18.                 StopAnimation("run");
    19.             }
    20.         }
    Last edited: May 20, 2018
    saucer_attack likes this.
  7. VampireLestat


    Oct 15, 2016
    I know this is old, but for others seeking the same answer, I believe that OP's problem has nothing to do with the
    call and is instead in the

    The final parameter of
    is the areaMask and the OP is passing in 1 here. Unity has 3 built in AreaMasks (seen in pic below) and 1 is for Not Walkable. Therefore, the SamplePosition call is likely failing and then being used to send bad info to CalculateMesh.

    Instead, set this mask to either be NavMesh.AllAreas (which is -1, just FYI) or to just the area masks you do want using a bitwise OR (e.g.,
    areaMask = 0 | 2
    to get Walkable and Jump areas).

    aleksandrhovhannisyan likes this.
  8. DonkeyPotato


    Mar 23, 2018
    This is incorrect. areaMask is a bit mask of the indices of areas.
    1 is the mask for Walkable. (1 << 0). ie, you're turning on the bit at index 0.
    If you want Walkable and Jumpable, it'd be
    areaMask = (1 << 0) | (1 << 2);

    Which ends up being an integer value of 3.
    The code you posted would generate an integer value of 2, and only set the bit for the Jumpable area.
    corb555 and stimul like this.