1
\$\begingroup\$

I am using the NavMeshSurface component in Unity to generate a navmesh of walkable areas in a procedurally generated level. I am working on some basic behavior to use with a NavMeshAgent. I want to find a random point for the agent to wander to, but I want to check if the position is within the walkable area before telling the agent to start navigating.

The problem is that I can't find a method to check if a point is within the NavMeshSurface. My search results reference the NavMesh having a similar method but not NavMeshSurface. Is there an easy way to check if the point is in bounds? Can I access the NavMesh and ray/sphere cast against it? Any solutions would be great. If there is a different free option, I am open to exploring it.

Thanks. Let me know if you require more information.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Can you access the NavMesh by getting NavMeshData from the NavMeshSurface and use that to test the point? Posting as a comment because I've not tried it. \$\endgroup\$ Sep 9 at 13:44
  • \$\begingroup\$ Navmeshdata has no way to operate on it directly. I wonder if you could make a navmesh and add the navmeshdata from the navmeshsurface and then use the functions in navmesh to query the data. Worth an experiment. \$\endgroup\$ Sep 9 at 14:23

1 Answer 1

2
\$\begingroup\$

If you just want to designate a random destination for the agent to wander to, you can use NavMeshSurface.NavMeshData.sourceBounds to find a point within the bounds of the NavMeshSurface. Sure, it will contain points that aren't strictly on the path, but in most cases this shouldn't really matter -- the agent will simply wander to the nearest point that is on the path.

Here is a test script. It assumes the navmeshsurface gameobject is at origin.

It resets the agents destination every 5 seconds.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class TestThing : MonoBehaviour
{
    public NavMeshSurface surface;
    NavMeshData data;
    public NavMeshAgent agent;
    public Transform target;

    float timer;

    Vector3 destination;


    
    void Start()
    {
        data = surface.navMeshData;
        agent.destination = SetRandomDest(data.sourceBounds);
        Debug.Log(data.sourceBounds);
        timer = 0;
    }



   //Update destination every 5 seconds to test
    void Update()
    {
        timer += Time.deltaTime;
        if(timer > 5)
        {
            agent.destination = SetRandomDest(data.sourceBounds);
            Debug.Log(data.sourceBounds);
            timer = 0;
        }
        
    }

    Vector3 SetRandomDest(Bounds bounds)
    {
        var x = Random.Range(bounds.min.x, bounds.max.x);
        var z = Random.Range(bounds.min.z, bounds.max.z);
     
        destination = new Vector3(x,1, z);
        target.position = destination;
        return destination; 
    }
}

Hope that helps.


 
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .