[This is preliminary documentation and is subject to change.]

The navigation mesh query is the most important class to understand since most navigation clients will interact with the query rather than the navigation mesh itself. The mesh contains the data, but the query provides almost all of the features necessary for pathfinding.

Core Class: NavmeshQuery

Query features fall into two general categories: Pathfinding and local search.

Pathfinding involves standard A* and Dijkstra searches that find the best path(s) between two points. Paths are made up of a list polygon references that represent a polygon corridor from the start to the end position. Path straightening is used to convert the path into a list of waypoints. (I.e. String pulling.)

The local search features offer various methods for locating polygons and points on polygons, and for querying the local environment. I.e. Raycasting, finding the distance to the nearest wall, etc.

Many of the query methods require a NavmeshQueryFilter. Filters define area traversal costs as well as flags used for including/excluding polygons and off-mesh connections from results.

The best way to understand the query class is to play around with it. The Sample Pack includes the Query Explorer demo that permits experimentation with all of the main query features.

Common Operations

This section contains some simple examples of common query operations.

Finding a Point in the Navigation Mesh

You can't do much without first getting a valid point on the navigation mesh. So the first step is to find one.

GetNearestPoint(Vector3, Vector3, NavmeshQueryFilter, NavmeshPoint%)

CopyC#
// Where 'query' is a NavmeshQuery object and 'filter' is a NavmeshQueryFilter object.
// 'position' is a Vector3 indicating the world position of the client.

NavmeshPoint result;
Vector3 extents = new Vector3(1, 1, 1);  // Keep this to the minimum extents practical.

NavStatus status = query.GetNearestPoly(position, extents, filter
        , out result);

if (result.polyRef == Navmesh.NullPoly)
{
        // Handle error.  Could not find a result.
        // The status can be checked to see if there was an error.  If not, then
        // the cause is that the search extents did not overlap any polygons.
}

// Use the result point, which includes a vector point and the reference of 
// the polygon that contains the point.

Basic Pathfinding

Even if you are planning to use PathCorridor or CrowdManager, you'll always need to do long distance planning using the basic NavmeshQuery features. First, get a path, then optionally straighten it.

CopyC#
// Where 'query' is a NavmeshQuery object and 'filter' is a NavmeshQueryFilter object.
// 'start' and 'end' are NavmeshPoints known to be on the navigation mesh.

int pathCount;
// The path will be a list of polygon references.
uint[] path = new uint[100];  // Size for maximum allowed path length.
NavStatus status;

if (start.polyRef == end.polyRef)
{
        // No need to do any planning.
        pathCount = 1;
        path[0] = start.polyRef;
}
else
{
        status = query.FindPath(start, end, filter, path
                , out pathCount);

        if (NavUtil.Failed(status) || path.pathCount == 0)
        {
                // Handle pathfinding failure.
        }
        else if (end.polyRef != path[pathCount - 1])
        {
            // Handle a partial path.
            // The query either could not reach the end point,
            // or the path buffer was too small to hold the
            // entire path.  (A check of 'status' will reveal if
            // the buffer was too small.)
        }

}

// If you need to straighten the path...

const int MaxStraightPath = 4;  // Just getting the first 4 waypoints.
int wpCount;

// The waypoints.
Vector3[] wpPoints = new Vecotr3[MaxStraightPath];

// A list of polygon references.  (The polygon being entered at each waypoint.)
uint[] wpPath = new uint[MaxStraightPath];

// The type of each waypoint. (Start, end, off-mesh connection.)
WaypointFlag[] wpFlags = new WaypointFlag[MaxStraightPath];

status = query.GetStraightPath(start.point
        , goal.point
        , path
        , 0                // The index of the start of the path.
        , pathCount        // The length of the path.
        , wpPoints
        , wpFlags
        , wpPath
        , out wpCount);

if (NavUtil.Failed(status) || wpCount == 0)
{
        // Handle the failure.  There should always be at least one waypoint 
        // (the goal) for a valid point/path combination,
}

// Use the path and waypoints.

See Also