Unity中的导航系统

发布时间:2023年12月22日

????????NavMesh(导航网格)是3D游戏世界中用于实现动态物体自动寻路的一种技术,将游戏中复杂的结构组织关系简化为带有一定信息的网格,在这些网格的基础上通过一系列的计算来实现自动寻路。导航时,只需要给导航物体挂载导航组建,导航物体便会自行根据目标点来寻找最直接的路线,并沿着该线路到达目标点。?

1.生成导航网格

选择菜单栏中的Windows - Navigation

打开后会出现以下面板

Navigation面板?

1.Object?

需要你在场景中选择一个带有网格渲染的游戏对象或者地形

我们在场景中添加一个cube,并点击它。

然后我们把Navigation Static给勾选上

Navigation Static

选择你想要使用的物体,把他们标记为‘导航静态(Navigation static)’这就会告诉Unity这些物体是静态的(非移动),在寻路的时候应该被考虑进去。

这个就是Navigation有关Object这一块,还有Generate OffMeshLinks和Navigation Area后面会讲。?

?2.Agents

agents也就是我们的导航代理,是个圆柱体。

Name:名字

Radius:半径

Height:高度

Step Height:每一步的高度

Max Slope:可以通过的斜坡的倾斜角,范围在0到60度

3.Areas

?

我们可以设置一些新的Area,右边那个值我们称为该层的行走代价(Cost),Cost值越大,行走的代价越高。

这个就可以用到,当有两条路径进行选择的时候,我们可以通过设置两个不同Cost的Area,让物体走向指定路径

设置的话在Object的Navigation Area上就可以选择(和inspector窗口的layer以及tag是一个用法)

4.Bake

Bake烘培参数面板

  • Radius:导航代理的半径,半径越小生成的网格面积越大。
  • Height:导航代理的高度。
  • Max Slope:导航代理能够行走的斜坡的最大坡度(最大60度)
  • Step Height:导航代理一步能跨越的台阶高度
  • Drop Height:地形网格的高度差,低于此值,导航代理可以跳落
  • Jump Distance:允许最大的跳跃距离。

单击该面板右下角的Bake按钮,就可以生成导航网格。

eg:

接着我们通过一个案例来简单讲讲使用:?

?案例1:通过鼠标点击实现移动到目标点

我们先来搭建一个这样的场景,一个Plane,两个蓝色的Cube作为障碍物,红色Cube是通过导航网络移动的物体,还有一个小球作为目标点。

我们先来实现通过导航到达小球位置。

将Plane还有两个障碍物的Navigation Static给勾选上,在点击Bake,就可以生成导航网络

导航网络建好后,我们选择需要寻路的物体,添加Nav MeshAgent组件。

Radius:物体的半径
Speed:物体的行进最大速度
Acceleration:物体的行进加速度
Augular Speed:行进过程中转向时的角速度。
Stopping Distance:离目标距离还有多远时停止。?

然后再添加一个脚本Cubenav

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;//NavMeshAgent所需要的命名空间
public class cubenav : MonoBehaviour
{
    private NavMeshAgent agent;
    public GameObject target;

    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
        agent.destination = target.transform.position;
    }
}

?运行结果:

?接着我们再实现鼠标点击的效果

我们改一下代码就行了,这里通过射线的方式实现

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;//NavMeshAgent所需要的命名空间
public class cubenav : MonoBehaviour
{
    private NavMeshAgent agent;
    public GameObject target;
    // Start is called before the first frame update
    void Start()
    {
        agent = GetComponent<NavMeshAgent>();
    }

    // Update is called once per frame
    void Update()
    {
        //agent.destination = target.transform.position;
        if (Input.GetMouseButton(0))
        {
            Ray ray = UnityEngine.Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit info;
            if (Physics.Raycast(ray, out info))//判断射线释放与碰撞器接触
            {
                if (info.collider.gameObject.tag == "floor")//将plane的tag设置为floor
                {
                    agent.destination = info.point;//RaycastHit类的point会返回射线碰到碰撞器的碰撞点
                }
            }
        }
    }
}

运行结果:

?OffMeshLinks:分离网格链接

分离网格链接用在不相连的导航区域间创建路径。

使用:

将两个plane的Generate OffMeshLinks勾选上

根据Bake中的这两个参数(如果两个plane满足这个条件),就可以Bake出分离网格链接

?

?这种方式会给出很多路径

如果想要单一路径的话

我们可以创建三个空对象

把start和end的position分别设置为两个平台的指定位置

再在link上添加Off Mesh Link组件,把start和end分别拖拽进来,再重新Bake(如果没反应,有可能是重合了,就调一下Bake中的那两个参数,使这两个平台不满足要求,这样我们看的也清楚一些)

这样就算不勾选上Generate OffMeshLinks,也能生成唯一的分离网格链接

文章来源:https://blog.csdn.net/weixin_63451038/article/details/135136627
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。