How to use NavMesh.CalculatePath() correctly

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.

/*
     * Choose a random point on the navmesh and set that point as your destination
     */
    void ChooseWaypoint()
    {
        float walkRadius = 300; //Radius in which to pick a point
        Vector3 randomDirection = Random.insideUnitSphere * walkRadius;
        randomDirection += transform.position;
        NavMeshHit hit;
        NavMesh.SamplePosition(randomDirection, out hit, walkRadius, 1);
        Vector3 finalPosition = hit.position;

        NavMeshPath path = new NavMeshPath ();
         if (NavMesh.CalculatePath (transform.position, finalPosition, NavMesh.AllAreas, path)) {
            Debug.Log ("Valid path has been found");
            destination = finalPosition;
        } else {
            Debug.Log("No path to that position, picking a new point");
            ChooseWaypoint();
        }

    }

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

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

1 Like

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?

3 Likes

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.

Same problem… all this time later. NavmeshAgent.SetPath from the same place works fine.

this thread is for 2015
but maybe you have the same problem .
1 . check Carve checkbox on navmeshObstacle
2. and try to use this

        NavMeshPath path = new NavMeshPath();
        if (NavMesh.CalculatePath(transform.position, _target, NavMesh.AllAreas, path))
        {
            bool isvalid = true;
            if (path.status != NavMeshPathStatus.PathComplete) isvalid = false;
            if (isvalid)
            {
                anim.SetBool(name, true);
                navMesh.SetDestination(_target);
                navMesh.isStopped = false;
                isActive = true;
            }
            else
            {
                navMesh.isStopped = true;
                isActive = false;
                StopAnimation("walk");
                StopAnimation("run");
            }
        }
1 Like

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).

4044277--351220--AreaMasks.png

1 Like

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.

2 Likes

I’ve had success using NavMesh.CalculatePath() with NavMeshPathStatus.PathComplete().
NavMeshPathStatus.PathPartial does not work reliably for me.

Dig this topic. How can i use NavMesh.CalculatePath() without to use a NavMeshAgent? I cant to use NavMeshAgent at my player, so i can to use just paths returning by NavMesh.CalculatePath() to move manualy my agent using path directions to simule InputDirections. Could anyone gimme this light?

Ohh jesus. Ok e see now. I dont need to use a navMeshAgent. Its work without.