Search Unity

How to use NavMesh.CalculatePath() correctly

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

  1. nostalgicbear

    nostalgicbear

    Joined:
    Mar 21, 2013
    Posts:
    94
    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;
    12.  
    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.         }
    21.  
    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

    nostalgicbear

    Joined:
    Mar 21, 2013
    Posts:
    94
    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

    Smithy43

    Joined:
    Sep 8, 2012
    Posts:
    7
    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

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    3,935
    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

    AmazingRuss

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

    irantutors

    Joined:
    May 16, 2018
    Posts:
    2
    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

    VampireLestat

    Joined:
    Oct 15, 2016
    Posts:
    5
    I know this is old, but for others seeking the same answer, I believe that OP's problem has nothing to do with the
    CalculatePath()
    call and is instead in the
    SamplePosition()
    call.

    The final parameter of
    SamplePosition()
    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).

    AreaMasks.png
     
    aleksandrhovhannisyan likes this.
  8. DonkeyPotato

    DonkeyPotato

    Joined:
    Mar 23, 2018
    Posts:
    5
    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.