NavMesh类常用方法


Unity - Scripting API: NavMesh (unity3d.com)

【Settings相关函数】

NavMesh.GetSettingsByID(agentTypeID);
NavMesh.GetSettingsByIndex(0);
NavMesh.GetSettingsCount();
NavMesh.GetSettingsNameFromID(agentTypeID);


NavMesh.CreateSettings();
NavMesh.RemoveSettings(agentTypeID); //只是删除运行后内存中的配置, 不会删除实际配置, 停止运行后就恢复了; 同时删除不会在当前帧立即删除, 而是会在后面的帧删除

var count = NavMesh.GetSettingsCount();
Debug.Log($"ct1: {count}");
for (var i = 0; i < count; ++i)
{
    var settings = NavMesh.GetSettingsByIndex(i);
    var settingsName = NavMesh.GetSettingsNameFromID(settings.agentTypeID);
    Debug.Log($"id: {settings.agentTypeID}, name: {settingsName}");
    if ("test" == settingsName)
    {
        NavMesh.RemoveSettings(settings.agentTypeID);
        --i;
    }
}
Debug.Log($"ct2: {count}");

# 输出结果

ct1: 3

index: 0, id: 0, name: Humanoid

index: 1, id: -1372625422, name: New Agent

index: 2, id: -334000983, name: test

ct2: 3

# settings name对应的是这边的name值:

【NavMeshBuildSettings属性的界面显示】

【NavMesh.SamplePosition】

# 在给定的点周边寻找一个在NavMesh上的点。

# distance参数,文档中的推荐值是agent高度的2倍,使用一个很大的值可能造成帧率降低。

# 这个脚本挂在orgin上,其中胶囊的位置在(4, 1, -2.34)

public class NavMeshTest : MonoBehaviour
{

    public NavMeshAgent _agent;
    public Transform _capsule;
    public float _distance = 1.0f;

    void Update()
    {
        if (Input.GetKey(KeyCode.Alpha1))
        {
            var srcPosition = _capsule.position;
            if (NavMesh.SamplePosition(srcPosition, out var hit, _distance, NavMesh.AllAreas))
            {
                Debug.Log($"hit: {hit.position}");
                Debug.DrawLine(srcPosition, hit.position, Color.red);
            }
        }
    }
    
}

# 最终distance参数为1.741才能在NavMesh上找到点。这里有点无法理解,不是x方向距离胶囊1就在NavMesh上了吗?最多再算上angent的radius就是1.5,为啥是1.741?

【NavMesh.FindClosestEdge】

# 离最近的边还有多少空间可以走

public class NavMeshTest : MonoBehaviour
{

    public Transform _capsule;

    void Update()
    {
        if (Input.GetKey(KeyCode.Alpha1))
        {
            var srcPosition = _capsule.position;
            if (NavMesh.FindClosestEdge(srcPosition, out var hit, NavMesh.AllAreas))
            {
                Debug.Log($"navMesh hit: {hit.position}, {hit.distance}");
                var center = srcPosition;
                center.y = 3;
                DrawCircle(center, hit.distance, Color.red);

                var endPos = hit.position;
                endPos.y = 3;
                Debug.DrawLine(center, endPos, Color.red);

                Debug.DrawRay(hit.position, Vector3.up * 10, Color.red);
            }
        }
        
    }

    void DrawCircle(Vector3 center, float radius, Color color)
    {
        Vector3 prevPos = center + new Vector3(radius, 0, 0);
        const int segCount = 10;
        for (int i = 0; i < segCount; i++)
        {
            float angle = (float)(i + 1) / (float)segCount * Mathf.PI * 2.0f;
            Vector3 newPos = center + new Vector3(Mathf.Cos(angle) * radius, 0, Mathf.Sin(angle) * radius);
            Debug.DrawLine(prevPos, newPos, color);
            prevPos = newPos;
        }
    }

}

【NavMesh.CalculatePath】

# 计算寻路的路径信息

public class NavMeshTest : MonoBehaviour
{
public Transform _capsule;
    public Transform _capsule2;private void Update()
    {
        if (Input.GetKey(KeyCode.Alpha1))
        {
            var srcPosition = _capsule.position;
            var targetPosition = _capsule2.position;
            NavMeshPath path = new NavMeshPath();
            if (NavMesh.CalculatePath(srcPosition, targetPosition, NavMesh.AllAreas, path))
            {
                var corners = path.corners;
                DrawCorners(ref corners);
            }
            Debug.Log($"cal path: {path.corners.Length}, {path.status}");
        }

        void DrawCorners(ref Vector3[] corners)
        {
            var color = Color.red;
            Vector3 prevPos = corners[0];
            for (int i = 1; i < corners.Length; i++)
            {
                var newPos = corners[i];
                Debug.DrawLine(prevPos, newPos, color);
                prevPos = newPos;
            }
        }
    }

}

# _capsule2在NavMesh上,且可达,NavMeshPathStatus.PathComplete

# _capsule2在NavMesh上,但那个NavMesh不可达,NavMeshPathStatus.PathPartial

# _capsule2不在NavMesh上,NavMeshPathStatus.PathInvalid

【其他】

NavMesh.AddLink(NavMeshLinkData data);

NavMesh.RemoveLink(NavMeshLinkInstance inst);

NavMesh.AddNavMeshData(NavMeshData data);

NavMesh.RemoveNavMeshData(NavMeshDataInstance inst);

NavMesh.RemoveAllNavMeshData();

相关