You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity 3D中如何获取NavMesh多边形及查询相关属性?

嘿,我来帮你梳理下Unity中NavMesh多边形相关的操作方案,刚好我之前也踩过这块的坑~

首先明确个事儿:Unity原生的NavMesh API其实藏了不少底层访问能力,只是有些功能得结合NavMeshQuery和NavMeshData来折腾,完全不需要额外下载第三方资源(当然如果嫌麻烦,Asset Store上有工具包能简化操作,但原生API足够搞定你的所有需求)。下面逐个解决你的问题:

Unity NavMesh 多边形操作全指南

1. 获取NavMesh的所有多边形

Unity没有直接返回所有多边形的一键API,但可以通过遍历NavMesh的网格数据来提取。核心思路是先拿到场景里的NavMeshData,再遍历里面的每个NavMeshTile,从Tile里抠出所有多边形:

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

public List<NavMeshPolygon> GetAllNavMeshPolygons()
{
    List<NavMeshPolygon> polygons = new List<NavMeshPolygon>();
    // 获取场景中激活的NavMesh数据
    NavMeshData navMeshData = NavMesh.GetNavMeshDataAtPosition(Vector3.zero);
    if (navMeshData == null) return polygons;

    foreach (NavMeshTile tile in navMeshData.tiles)
    {
        // 遍历当前Tile下的所有多边形
        for (int i = 0; i < tile.polygonCount; i++)
        {
            NavMeshPolygon polygon = tile.GetPolygon(i);
            polygons.Add(polygon);
        }
    }
    return polygons;
}

小提示:NavMeshPolygon里包含了多边形的顶点索引、面积、所属区域等信息,要拿具体顶点坐标的话,用tile.GetVertex(polygon.vertices[j])就行。

2. 找到最近的NavMesh多边形

直接用NavMesh.SamplePosition配合多边形索引就能搞定,这个方法会返回离目标点最近的NavMesh表面点,同时带该点所属的多边形信息:

public NavMeshPolygon FindNearestPolygon(Vector3 worldPos)
{
    NavMeshHit hit;
    // 第二个参数是搜索半径,可根据场景调整;最后一个参数是指定要搜索的NavMesh区域
    if (NavMesh.SamplePosition(worldPos, out hit, 10f, NavMesh.AllAreas))
    {
        NavMeshData navMeshData = NavMesh.GetNavMeshDataAtPosition(worldPos);
        if (navMeshData == null) return null;

        // 通过hit里的索引找到对应的Tile和多边形
        NavMeshTile tile = navMeshData.tiles[hit.meshDataIndex];
        return tile.GetPolygon(hit.polygonIndex);
    }
    return null;
}

3. 获取多边形的中心

有两种方式:手动计算顶点平均值,或者用NavMeshQuery的原生方法更高效:

public Vector3 GetPolygonCenter(NavMeshPolygon polygon, NavMeshTile tile)
{
    // 方法1:手动计算顶点平均值(适合新手理解)
    Vector3 center = Vector3.zero;
    for (int i = 0; i < polygon.vertexCount; i++)
    {
        center += tile.GetVertex(polygon.vertices[i]);
    }
    center /= polygon.vertexCount;
    return center;

    // 方法2:用NavMeshQuery的原生方法(性能更好)
    // NavMeshQuery query = new NavMeshQuery();
    // query.SetNavMeshData(NavMesh.GetNavMeshDataAtPosition(Vector3.zero));
    // Vector3 center;
    // query.GetPolyCenter(polygon.polygonID, out center);
    // return center;
}

4. 找到与特定多边形相连的多边形

可以用NavMeshQuery的FindConnectedPolys方法直接获取相邻多边形的ID,再转成对应的多边形对象:

public List<NavMeshPolygon> GetConnectedPolygons(NavMeshPolygon targetPoly, NavMeshData navMeshData)
{
    List<NavMeshPolygon> connectedPolys = new List<NavMeshPolygon>();
    NavMeshQuery query = new NavMeshQuery();
    query.SetNavMeshData(navMeshData);

    // 获取目标多边形的ID,再查找所有相连的多边形ID
    PolyId targetPolyId = targetPoly.polygonID;
    List<PolyId> connectedPolyIds = new List<PolyId>();
    query.FindConnectedPolys(targetPolyId, NavMesh.AllAreas, connectedPolyIds);

    // 把ID转成具体的多边形对象
    foreach (PolyId polyId in connectedPolyIds)
    {
        int tileIndex = query.GetTileIndexFromPolyId(polyId);
        NavMeshTile tile = navMeshData.tiles[tileIndex];
        int polyIndex = query.GetPolyIndexFromPolyId(polyId);
        connectedPolys.Add(tile.GetPolygon(polyIndex));
    }
    return connectedPolys;
}

关于第三方资源的补充

如果觉得原生API写起来太繁琐,Asset Store上有一些工具包(比如NavMesh Plus)能封装这些操作,让代码更简洁,但原生API完全能满足你的需求,不需要额外付费或下载GitHub资源。

另外你提到的论坛帖子只获取顶点,是因为它用的是早期的API,现在Unity的NavMeshData和NavMeshTile提供了更完整的多边形访问能力,放心用就行~

内容的提问来源于stack exchange,提问作者Vlad

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:58:27