Unity NavMeshCopmonent使用说明

Unity导航系统NavMesh系统包括:NavMesh、NavMeshAgent、NavMeshObstacle、OffMeshLink

一、Navigation(导航设置)
1、Aents(寻路者)
编辑寻路者类型
Name:类型名
Radius:寻路者半径
Height:寻路者高度
Step Height:台阶高度
Max Slope:斜坡的坡度

2、Areas(区域)
Name:区域名
Cost:寻路区域开销
定义了穿越特定区域的难度,在寻路期间将优先选择成本较低的区域
按颜色区分Bake后的区域类型(Walkable、NotWalkable、Jump等)

3、Bake(烘焙)
Agent Radius: 定义代理中心与墙壁或窗台的接近程度
Agent Height: 定义代理可以达到的空间有多低
Max Slope: 定义代理走上坡道的陡峭程度
Step Height: 定义代理可以踏上的障碍物的高度

Drop Height:允许跳跃最大下落距离,怎么使用?
Jump Distance:允许最大的跳跃距离,怎么使用?

Manual Voxel Size:手动输入像素值?
Min Region Area:网格面积小于该值则不生成导航网格
Height Mesh:选中该项,将会保存高度信息,同事也会消耗一些性能和存储空间

4、Object(设置场景中对象是否参与导航网格烘焙)
Navigation Static : 勾选后表示该对象参与导航网格的烘焙
Generate OffMeshLinks : 勾选后可以跳跃导航网格和下落
Navigation Area : 物体烘焙网格属于哪个图层, 可通过代码让游戏人物走不同的路

二、NavMesh的组件:
1、NavMeshAgent
2、NavMeshObstace
3、NavMeshLink
4、NavMeshModifier
5、NavMeshModifierVolume
6、NavMeshSurface

1、Nav Mesh Agent - 组件(寻路者)
Agent Type : 寻路者类型
Base Offset : 偏移度

Steering(操控)
Speed :移动速度
Angular Speed :移动过程中转向角速度
Acceleration :加速度
Stopping Distance : 距离目标点小于多远距离后停止移动

Obstacle Avoidance(躲避障碍参数)
Radius: 半径
Height:高度
Quality: 质量
Priority: 优先级

Path Finding(路径寻找)
Auto Traverse Off Mesh Link : 是否采用默认方式度过连接路径
Auto Repath : 在行进过程中,因某些原因中断的情况下,是否重新开始寻路
Auto Mash : 自动遮罩

2、Nav Mesh Surface - 组件
1、说明:NavMeshSurface组件可以被加在任何游戏物体上,可以用来定义那些物体可以用来生成NavMesh(有了该组件后可以不需要设置物体Navigition static的静态属性,以前的静态属性只适用于editor模式,不适用于实时bake的特性)

2、参数
(1)、Agent Type: 用来匹配NavMeshAgent

(2)、Collect Object: 定义哪些物体用来bake生成NavMesh
All: 使用全部激活状态的物体(无论是否是父子物体)
Volume: 被体积盒包围的物体,或者是包围在内的物体的部分
Children: 有NavMeshSurface组件的物体及其子物体

(3)、Include Layers: 定义哪些层的物体要被bake

(4)、Use Geometry: 选择使用网格或者碰撞体来bake
Render Meshes - 使用Mesh Renderer 和 Terrains
Physics Colliders - 使用Colliders和Terrains(推荐)

Advanced:高级设置(一般默认就可以)
Default Area: 默认生成区域类型

Override Voxel Size: 覆盖默认的Voxel Size,体素尺寸,用来调整精度,场景比较精密的可以把该值调小,值越小精度越高,精度越高,bake越慢,该值与Tile Size共同影响bake的效果

Override Tile Size: 覆盖默认的Tile Size,块大小,默认是256voxel作为一块,为了让bake有较多平行与增加内存效率才有了此设置,在障碍物多的时候,可以将块减小以提升运行效率。或者打算实时bake的时候,可以用更小的Tile Size来降低内存消耗

Build Height Mesh: 不再被支持

*提示:NavMesh Surface组件用来设置一片大范围内要被bake的物体的信息,而用NavMeshModifer组件可以对这些物体逐个进行微调

3、NavMeshModifer - 组件
说明:将某些游戏对象标记为某种区域类型。
参数:
Ignore From Build:烘焙过程中排除游戏对象及其所有子项。
Override Area Type:更改包含修改器的游戏对象及其所有子项的区域类型。
Area Type:从下拉菜单中选择要应用的新区域类型。
Affected Agents:修改器影响的一系列代理 (Agent)。例如,可选择为特定代理排除某些障碍物。

4、NavMeshModiferValue - 组件
说明:将一个已定义的区域标记为特定类型,而NavMeshModifer会将某些游戏对象标记为某种区域类型。

参数:
Size:导航网格修改器体积的尺寸,由 XYZ 测量值定义。
Center:相对于游戏对象中心的导航网格修改器体积的中心,由 XYZ 测量值定义。
Area Type:导航网格修改器体积适用的区域类型。
Affected Agents:导航网格修改器体积影响的一系列代理 (Agent)。例如,可选择仅针对特定代理类型将选定的导航网格修改器体积标记为危险区域。

5、NavMeshLink -组件
说明:在使用导航网格的两个位置之间创建可导航的链接。此链接可以是点到点,也可以跨越间隙,在后一种情况下,代理 (Agent) 使用沿着入口边缘的最近位置来跨越链接。必须使用导航网格链接来连接不同的导航网格表面。
参数:
Agent Type:可使用该链接的代理类型。
Start Point:链接起点(相对于游戏对象)。由 XYZ 测量值定义。
End Point:链接终点(相对于游戏对象)。由 XYZ 测量值定义。
Align Transform To Points:单击此按钮可将游戏对象移到链接的中心点,并将变换的前向轴与终点对齐。
Bidirectional:选中此复选框时,导航网格代理 (NavMesh Agent) 会双向遍历导航网格链接(从起点到终点,再从终点回到起点)。
取消选中此复选框时,导航网格链接仅单向运行(仅从起点到终点)。
Area Type:导航网格链接的区域类型(这会影响寻路成本)。

三、Bake一个地图
1、使用Navigation(Window-AI-Navigation)生成寻路NavMesh
设置寻路者参数Agents
设置区域Areas
设置对象Object,将场景中需要烘焙的物体设为Static
设置烘焙Bake参数,点击Bake按钮。同时会在场景同级目录下,生成一个同名场景的文件夹,文件夹里生成NavMesh.asset的烘焙文件

2、使用NavMeshSurface生成寻路NavMesh

四、编辑一个自定义的NavMesh

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

// Build and update a localized navmesh from the sources marked by NavMeshSourceTag
[DefaultExecutionOrder(-102)]
public class LocalNavMeshBuilder : MonoBehaviour
{
    // The center of the build
    public Transform m_Tracked;

    // The size of the build bounds
    public Vector3 m_Size = new Vector3(80.0f, 20.0f, 80.0f);

    NavMeshData m_NavMesh;
    AsyncOperation m_Operation;
    NavMeshDataInstance m_Instance;
    List<NavMeshBuildSource> m_Sources = new List<NavMeshBuildSource>();

    IEnumerator Start()
    {
        while (true)
        {
            UpdateNavMesh(true);
            yield return m_Operation;
        }
    }

    void OnEnable()
    {
        // Construct and add navmesh
        m_NavMesh = new NavMeshData();
        m_Instance = NavMesh.AddNavMeshData(m_NavMesh);
        if (m_Tracked == null)
            m_Tracked = transform;
        UpdateNavMesh(false);
    }

    void OnDisable()
    {
        // Unload navmesh and clear handle
        m_Instance.Remove();
    }

    void UpdateNavMesh(bool asyncUpdate = false)
    {
        NavMeshSourceTag.Collect(ref m_Sources);
        var defaultBuildSettings = NavMesh.GetSettingsByID(0);
        var bounds = QuantizedBounds();

        if (asyncUpdate)
            m_Operation = NavMeshBuilder.UpdateNavMeshDataAsync(m_NavMesh, defaultBuildSettings, m_Sources, bounds);
        else
            NavMeshBuilder.UpdateNavMeshData(m_NavMesh, defaultBuildSettings, m_Sources, bounds);
    }

    static Vector3 Quantize(Vector3 v, Vector3 quant)
    {
        float x = quant.x * Mathf.Floor(v.x / quant.x);
        float y = quant.y * Mathf.Floor(v.y / quant.y);
        float z = quant.z * Mathf.Floor(v.z / quant.z);
        return new Vector3(x, y, z);
    }

    Bounds QuantizedBounds()
    {
        // Quantize the bounds to update only when theres a 10% change in size
        var center = m_Tracked ? m_Tracked.position : transform.position;
        return new Bounds(Quantize(center, 0.1f * m_Size), m_Size);
    }

    void OnDrawGizmosSelected()
    {
        if (m_NavMesh)
        {
            Gizmos.color = Color.green;
            Gizmos.DrawWireCube(m_NavMesh.sourceBounds.center, m_NavMesh.sourceBounds.size);
        }

        Gizmos.color = Color.yellow;
        var bounds = QuantizedBounds();
        Gizmos.DrawWireCube(bounds.center, bounds.size);

        Gizmos.color = Color.green;
        var center = m_Tracked ? m_Tracked.position : transform.position;
        Gizmos.DrawWireCube(center, m_Size);
    }
}
using UnityEngine;
using UnityEngine.AI;
using System.Collections.Generic;

// Tagging component for use with the LocalNavMeshBuilder
// Supports mesh-filter and terrain - can be extended to physics and/or primitives
[DefaultExecutionOrder(-200)]
public class NavMeshSourceTag : MonoBehaviour
{
    // Global containers for all active mesh/terrain tags
    public static List<MeshFilter> m_Meshes = new List<MeshFilter>();
    public static List<Terrain> m_Terrains = new List<Terrain>();

    void OnEnable()
    {
        var m = GetComponent<MeshFilter>();
        if (m != null)
        {
            m_Meshes.Add(m);
        }

        var t = GetComponent<Terrain>();
        if (t != null)
        {
            m_Terrains.Add(t);
        }
    }

    void OnDisable()
    {
        var m = GetComponent<MeshFilter>();
        if (m != null)
        {
            m_Meshes.Remove(m);
        }

        var t = GetComponent<Terrain>();
        if (t != null)
        {
            m_Terrains.Remove(t);
        }
    }

    // Collect all the navmesh build sources for enabled objects tagged by this component
    public static void Collect(ref List<NavMeshBuildSource> sources)
    {
        sources.Clear();

        for (var i = 0; i < m_Meshes.Count; ++i)
        {
            var mf = m_Meshes[i];
            if (mf == null) continue;

            var m = mf.sharedMesh;
            if (m == null) continue;

            var s = new NavMeshBuildSource();
            s.shape = NavMeshBuildSourceShape.Mesh;
            s.sourceObject = m;
            s.transform = mf.transform.localToWorldMatrix;
            s.area = 0;
            sources.Add(s);
        }

        for (var i = 0; i < m_Terrains.Count; ++i)
        {
            var t = m_Terrains[i];
            if (t == null) continue;

            var s = new NavMeshBuildSource();
            s.shape = NavMeshBuildSourceShape.Terrain;
            s.sourceObject = t.terrainData;
            // Terrain system only supports translation - so we pass translation only to back-end
            s.transform = Matrix4x4.TRS(t.transform.position, Quaternion.identity, Vector3.one);
            s.area = 0;
            sources.Add(s);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值