finding closest point on navmesh

I have a random wander script, it works fine as a prototype / testing so long as its on a flat surface and no obstacles, but now I want to clean it up some and have it use the navmesh

so this random wander script waits a random amount of time and then generates a point (vector3)

how can I then take that vector3 and find the closest point on navmesh? I’ve seen bits and pieces of like a navmesh.sample and some navmeshhit but I’m completely out of my element with these, so can someobody point me in the right direction? how would I take this random Vector3 point and get out a vector3 that is a point on the navmesh?

Here is some code that is similar to what I am using. Hope this helps:

public float distanceToNewPoint = 25f; //how far away is the new point
NavMeshPath path = new NavMeshPath();
Vector3 newDest;
do {
    //random vector3
    Vector3 randomDirection = new Vector3 (Random.value, Random.value, Random.value);
    //set the magnitude of the vector3 (this could be randomized too if you want)
    randomDirection *= distanceToNewPoint;
    //randomly pick a negative value for the x or z
    if (Random.Range(0,2) == 0) randomDirection.x *= -1;
    if (Random.Range(0,2) == 0) randomDirection.z *= -1;
   
    //add the random vector to the current position
    Vector3 v = transform.position + randomDirection;
   
    //determine the y value by looking at the terrain height
    float y;
    y = Terrain.activeTerrain.SampleHeight (v) + Terrain.activeTerrain.transform.position.y;

    newDest = new Vector3 (v.x, y, v.z);
   
    //calculate the path
    agent.CalculatePath(newDest, path);
    Debug.Log(path.status);
    yield return null;
} while (path.status != NavMeshPathStatus.PathComplete); //keep looking for a new random value until the path is complete meaning it's a valid path
1 Like

Is this what you are looking for?
http://docs.unity3d.com/ScriptReference/NavMesh.SamplePosition.html

If so, it’s simple to use;

NavMeshHit myNavHit;
if(NavMesh.SamplePosition(transform.position, out myNavHit, 100 , -1))
{
transform.position = myNavHit.position;
}

That should snap the object onto the navmesh as long as it’s within a range of 100 units.

10 Likes

not sure understand why somethink’s like that’s does’t works
if (canWalk) {

Vector3 vv = transform.position;
vv += moveDirection * Time.fixedDeltaTime;

NavMeshHit myNavHit;
if (NavMesh.SamplePosition (vv,out myNavHit,2,-1)){

collisionFlags = m_Controller.Move (moveDirection * Time.fixedDeltaTime);

}

}

Saved my RTS. Thank you, my dude.

It was 4/5 years ago so unsure if they will even get your message :stuck_out_tongue:

This is really great it saved my rts too thanks :smile:

1 Like