Version: Unity 6.5 (6000.5)
LanguageEnglish
  • C#

NavWorld.GetEdgesAndNeighbors

Suggest a change

Success!

Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

Close

Submission failed

For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

Close

Cancel

Declaration

public NavQueryStatus GetEdgesAndNeighbors(NavNode node, NativeSlice<Vector3> edgeVertices, NativeSlice<NavNode> neighbors, NativeSlice<byte> edgeIndices, out int verticesCount, out int neighborsCount);

Parameters

Parameter Description
node The identifier of the node from a NavMesh surface or a NavMesh Link to retrieve the vertices and neighbors for.
edgeVertices The result buffer that receives the world positions describing the geometry of the input navigation node. It can have zero capacity.
neighbors The result buffer that holds the identifiers of all the navigation nodes immediately reachable from the specified node. It can have zero capacity.
edgeIndices The helper result buffer that maps each neighbor node to an edge of the specified node. It can have zero capacity.
verticesCount The total number of vertices that describe the geometry of the input node. This is independent of the capacity of the edgeVertices result buffer.
neighborsCount The total number of navigation nodes the input node connects to. This is independent of the capacity of the result buffers (neighbors and edgeIndices).

Returns

NavQueryStatus A bitfield with one of the following two main flags set:

Success if Unity can evaluate the neighbors and vertices of the specified node, regardless of the result. The verticesCount and neighborsCount are always valid in this case.

Failure if Unity can't use the node identifier to retrieve the neighbors or geometry information. Unity doesn't modify any of the five result parameters (edgeVertices, neighbors, edgeIndices, verticesCount, or neighborsCount) in this case.

InvalidParameter is part of the returned flags if the specified navigation node isn't valid in the query's NavWorld.

MoreDataAvailable is part of the flags that Unity returns from this method when any of the result buffers you provide aren't large enough to hold all the neighbor nodes the input node connects to, or all of its edge vertices.

Description

Retrieves the vertices of a specified node and the identifiers of all the navigation nodes to which it connects.

Polygonal nodes of the NavMesh have a minimum of three and a maximum of six vertices, while link nodes always have four vertices regardless of their width. The index of an element in edgeIndices is also an index in the neighbors array, and the value of that edgeIndices element is an index in the edgeVertices array.

A polygon of a NavMesh surface connects to all other neighboring polygons with which it shares an edge, as well as all the NavMesh Links that leave from anywhere on its surface. The polygon doesn't connect to other polygons with which it shares only a vertex.

Each point returned in the edgeVertices array represents the start of a node's edge and the subsequent element in the array is the end point of that edge. All vertices form a closed polygonal line. The last and first elements define the last edge.

A NavMesh Link connects to all the NavMesh polygons that each end of the link intersects with, regardless of whether the link is unidirectional.

For link nodes, the returned edgeVertices array contains two pairs of points, at indexes [0] and [1], and at indexes [2] and [3], that define the end points of the start and end edges of the link, in this order. These are the world positions that Unity establishes when it instantiates the link in the NavMesh world. For nodes of NavMesh Links with the width set to 0, the pairs contain the same value in both of their elements.

A node from the neighbors array lies at the edge returned in edgeIndices at the same index.

If both the specified node and its neighbor are NavMesh polygons, then the corresponding edgeIndices value represents the index of the polygon edge that leads from node to the neighbor. For example, edgeVertices[edgeIndices[2]] represents the start point of the edge that is common between node and the neighbors[2] node, and edgeVertices[edgeIndices[2] + 1] is the end point of that edge.

A NavMesh polygon can have a maximum of 6 edges. This means the edgeIndices value corresponding to a polygon-polygon connection is from 0 to 5. An edge usually connects only the two polygons that share it, but edges that sit at a tile border can connect one polygon in the first tile to multiple polygons in the second tile. In this case, edgeIndices report the same value for all of those neighbors.

If either the specified node or the neighbor is a link, then the corresponding edgeIndices value represents the side on the link where the connection is made: 0 for start and 2 for end. When the node is a polygon and the neighbor is a link, the value acts only as information about the side of the link where the two nodes connect. Don't use it as an index in the edgeVertices array.

When the neighbors and edgeIndices buffers both have positive capacity, they must be the same size. Otherwise, Unity throws an ArgumentException when this method executes in the Editor.

You can set any of the buffers to have zero capacity for the cases when you don't need the results.

The returned verticesCount and neighborsCount values express the number of elements that comprise the result in the output buffers of sufficient size. Unity still fills buffers that aren't large enough with valid nodes, up to their full capacity.

The five result parameters (edgeVertices, neighbors, edgeIndices, verticesCount, and neighborsCount) don't act as input and don't change the internal navigation data in any way. Unity modifies them only when the operation returns a Success status.

Additional resources: NavWorld.GetNodeType, NavWorld.GetPortalPoints

using Unity.Collections;
using UnityEngine;
using Unity.AI.Navigation.LowLevel;

public class NavMeshNodeEdgesDrawer : MonoBehaviour
{
    void Update()
    {
        using NavWorld query = NavWorld.GetDefaultWorld();

        // A NavMesh polygon has at most 6 vertices, so this buffer holds a complete outline.
        using NativeArray<Vector3> vertices = new NativeArray<Vector3>(6, Allocator.Temp);
        using NativeArray<NavNode> neighbors = new NativeArray<NavNode>(10, Allocator.Temp);
        using NativeArray<byte> edgeIndices = new NativeArray<byte>(neighbors.Length, Allocator.Temp);

        NavLocation location = query.MapLocation(transform.position, Vector3.one, 0);

        NavQueryStatus queryStatus = query.GetEdgesAndNeighbors(
            location.node, vertices, neighbors, edgeIndices,
            out int totalVertices, out int totalNeighbors);

        bool succeeded = (queryStatus & NavQueryStatus.Success) != 0;
        Debug.DrawLine(transform.position - Vector3.up, transform.position + Vector3.up,
            succeeded ? Color.green : Color.red);

        // On failure the counts and the buffers are left untouched, so stop here.
        if (!succeeded)
            return;

        // The reported counts describe the whole node and can be larger than the buffers you
        // passed in, so clamp them before you use them as indices.
        int drawnVertices = Mathf.Min(totalVertices, vertices.Length);
        int drawnNeighbors = Mathf.Min(totalNeighbors, neighbors.Length);

        for (int i = 0, j = drawnVertices - 1; i < drawnVertices; j = i++)
        {
            Debug.DrawLine(vertices[i], vertices[j], Color.grey);
        }

        for (int i = 0; i < drawnNeighbors; i++)
        {
            if (query.GetNodeType(neighbors[i]) == NavNodeType.Link)
            {
                // The link neighbor is not connected through any of the polygon's edges.
                // Call GetEdgesAndNeighbors() on this specific neighbor in order to retrieve its edges.
                continue;
            }

            // For a polygon-to-polygon connection the edge index points into the vertex buffer.
            byte start = edgeIndices[i];
            if (start >= drawnVertices)
                continue;

            int end = (start + 1) % drawnVertices;
            Color neighborColor = Color.Lerp(Color.yellow, Color.magenta,
                (float)start / Mathf.Max(1, drawnVertices - 1));
            Debug.DrawLine(vertices[start], vertices[end], neighborColor);
        }
    }
}