Unity零基础到入门 ☀️| 万字教程 对 Unity 中的 Navigation导航系统基础 全面解析+实战演练收藏不迷路

Posted 呆呆敲代码的小Y

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity零基础到入门 ☀️| 万字教程 对 Unity 中的 Navigation导航系统基础 全面解析+实战演练收藏不迷路相关的知识,希望对你有一定的参考价值。

  • 📢博客主页:https://blog.csdn.net/zhangay1998
  • 📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
  • 📢本文由 呆呆敲代码的小Y 原创,首发于 CSDN🙉
  • 📢未来很长,值得我们全力奔赴更美好的生活✨


📢前言

  • 最近收到小伙伴的留言,说基础学习的专栏写的挺不错的,适合新入门的学习。
  • 那我写这个Unity基础知识的专栏,就能感受到付出的心血没有白费呀!
  • 也希望自己写的东西能给更多的小伙伴带来更好的知识学习体验~
  • 之前写过几篇Unity基础学习的文章,但是有些地方还没有写,后面有时间就慢慢补齐!
  • 所以这篇文章就对Unity中的导航系统进行一个详细学习说明,感兴趣的小伙伴一起往下看吧!

❤️Unity Navigation 导航系统

导航系统,顾名思义,就是游戏中的一个寻路功能

现实世界中的导航则是输入一个起点和一个终点,我们的导航软件就会规划出一个合适的行进路线。

导航系统会帮我们选出最快捷最方便的那条路,然后我们顺着路线行走就可以到达目的地了!
虚拟世界中亦是如此。

比如许多游戏中,领取一个任务,然后有一个自动寻路,点击之后我们的角色就是自己动起来向着目的地进发。那小伙伴们有没有想过这个自动寻路是怎样实现的呢~

还有就是在场景中,鼠标点击某个位置,我们的角色就会慢悠悠的向着我们点击的位置移动过去,直到目标位置才停下来!比如英雄联盟,诸如此类

这就是最普通的一个导航思路,导航在大多数游戏中都会用到
包括我之前写过的那一篇复刻皇室战争的小游戏中就用到了导航系统!

因为上次是实战文章,所以对这个导航并没有过多的描述,只是简单的介绍了下游戏中是如何操作的。

Unity中常用的导航系统无非就是NavigationA*寻路,那本篇文章就开始正式介绍一下Navigation


🧡Navigation 导航系统概述

描述:一个角色在特定环境下自动到达指定目标

Unity 3D Navigation(导航)是用于实现动态物体自动寻路的一种技术,它将游戏场景中复杂的结构关系简化为带有一定信息的网格,并在这些网格的基础上通过一系列相应的计算来实现自动寻路。

是Unity自带的一个寻路系统,我们可以利用他完成非常多的导航功能。

我们只需要对角色和场景进行一个简单的设置就可以完成一个简单的实例

下面一起看看Navigation 中的详细结构吧!


💛导航网格(NavMesh)

想要使用Navigation进行导航

第一步,将场景中的从头至尾不会发生位置变化的物体设置成静态场景

这个很简单,选中想要设置的物体,然后在Inspector属性面板上设置一下Static就好了

如下图

第二步,网格烘焙

打开菜单栏,Windows - > AI ->Navigation

不同版本的可能Navigation的位置有所差异,找到后点击一下就好啦


点完之后,在面板上会出现一个Navigation,打开Bake窗口如下所示:

Bake界面有几个属性可以配置

  • Agent Radius (⻆⾊半径)
  • Agent Height (⻆⾊⾼度)
  • Max Slope (⻆⾊可以爬的最⼤坡度)
  • Step Height (⻆⾊可以上的台阶⾼度)

没有什么要求的时候,默认属性就好,然后单击面板右下角的Bake进行烘焙

烘焙完成后就可以看到如下图所示的烘焙完成的导航网格啦,还有会出现一个和场景同名的文件夹,保存导航网格烘焙的数据

其中这个蓝色的网格部分就是烘焙完成后,我们的导航可以进行移动的区域

未变蓝的区域就代表不能在该地区移动

那这个时候就有小伙伴进行提问了,明明场景都是一样设置的,为什么有的变蓝了,有的没变蓝呢!

这就是我们刚才设置的那个Bake造成的,因为默认的属性角色半径可能过大,所以场景中的边缘时导航无法到达的!所以就为渲染成蓝色可导航区域

所以看下面我把半径设置为0.1之后,基本上就都可以到达啦!

然后简单设置一个场景,让这个小胶囊体待会走的时候会动动脑子


💚导航角色(NavMeshAgent)

场景布置完了,导航网格设置好了,下一步就是给需要进行导航的物体添加上NavMeshAgent组件

🚩NavMeshAgent属性面板介绍

一起来看看NavMeshAgent的属性面板

介绍一下该组件的属性面板
AgentSize(角色大小)

  • Radius(半径)
  • Height(⾼度)
  • Base Offset(偏移量)
    导航⻆⾊与⽹格;中⼼点的偏移量

Steering(导航过程)

  • Speed(导航过程中
  • ⻆⾊的最⼤速度)
  • AngularSpeed(⻆速度)
  • Acceleration(加速度)
  • Stoping Distance(停⽌距离)
    当前⻆⾊距离⽬标多远时停下
  • Auto Breakting(⾃动减速)
    当⻆⾊快达到⽬标时⾃动减速

Obstacle Avoidance(躲避障碍物)

  • Quality(导航质量)
  • Priority(优先级)

Path Finding(寻路设置)

  • Auto Traverse Off Mesh Link
    ⾃动跨越分离路⾯
  • Auto Repath
    ⾃动重新规划路径
  • Area Mask
    分层剔除(设置⻆⾊可以⾛哪些层)

🚩常用属性和方法

下面是导航角色常用的一些属性方法介绍


知道了NavMeshAgent的面板属性和常用属性和方法之后

我们来写一个脚本,简单的执行一下导航,看一看到底是个啥效果呢!

创建一个NavigationTest脚本,代码如下

Tip:使用NavMeshAgent组件要先导入UnityEngine.AI命名空间,要不然会报错的哦!

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;//导入命名空间

public class NavigationTest : MonoBehaviour
{
    private NavMeshAgent navMeshAgent;

    private void Start()
    {
        navMeshAgent = gameObject.GetComponent<NavMeshAgent>();
    }

    private void Update()
    {
        if (Input.GetMouseButtonDown(0))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                Transform parent = hit.collider.transform.parent;
                if (parent != null )
                {
                    navMeshAgent.SetDestination(hit.point);
                }
            }
        }
    }
}

脚本内容很简单,就是拿到这个NavMeshAgent组件之后

  • Update中进行判断,当点击鼠标左键的时候
  • 开启射线检测,记录下当前鼠标点击的物体
  • 然后利用SetDestination方法,将鼠标点击的位置设置成导航的目的地

这样就会出现,我们鼠标点击一个位置,只要导航能到的地方就会按照导航自动计算出的最短路径进行自动寻路了!

将这个脚本挂到这个胶囊体上就好了,下面是演示效果:

Tip:如果胶囊体上不去这个台阶,那就是说明BakeStep Height(⻆⾊可以上的台阶⾼度)数值太小,适当改一下即可

这里还有一个小知识,就是我们在寻路的时候,我们寻路的角色在Scene场景中会出现三个红蓝黑箭头,如下图所示

  • 红⾊箭头 :代表 指向(阶段性⽬标)
  • 蓝⾊箭头 :代表 期望速度
  • ⿊⾊箭头 :代表 瞬时速度

💘分层路面导航(Nav Mesh Area)

🚩Areas简介

分层路面导航是什么意思呢?

在现实世界中进行导航的时候,可能会出现几条不同的路线

有的可能是走高速公路,有的则是跑下道,就是不上高速,走一些乡间土路之类的路径

因为走不同的路线付出的代价是不一样的,跑高速很快又省时间,但是要交高速费用

跑下道呢,不用交高速费,但是可能有很多红灯耽误时间,而且有时候路还不好走!

那Unity的这个分层路面导航呢,就是模拟现实世界中的不同的地形场景!

简单来说可以比喻成不同的地形,比如高速公路、乡间土路、河流和沙漠等等!

🚩Areas属性面板

先来看一下属性面板

切换至Navigation面板的Areas

前三个是Unity内置的三种地形:Wakeable可行走NotWakeable不可行走Jump跳跃

User1 - User31这一块都是我们可以进行设置的

比如上图,是我自己设置了两个:River(河流)Desert(沙漠)

设置完了之后,选中场景中的一个游戏对象,我这里选择的是左边的一条路,设置成了Desert沙漠,右边的设置成了River河流

然后回到Bake,重新烘焙一下,就会发现场景中的导航网格变颜色了,不再是蓝色

而是我们设置的颜色,我们在Area面板设置的两个地形分别是粉红色小绿色,所以导航网格变成了对应的颜色

如下图

🚩Areas实际应用

设置完了之后,我们重新运行场景会发现并没有什么作用,导航该咋咋滴,没有受到影响

再回到Area界面,会发现右面每一个User后面对应一个可以输入的Cost数值,不同Unity版本可能没有这个Cost标记

这个数值的含义可以理解为:行走该地形所要付出的“代价”

什么意思呢,比如我们把River河流后边的数值改成10,我们场景中右边那条路设置地形的为河流,导航网格是粉红色

下面运行程序看一下效果

我们明明从右边过过去会更近,但是我们的导航还是从左边绕远路过去,这就是因为我们给右边的路径设置的代价很高

所以导航会进行取舍,宁愿走远路也不会走这条代价更高的路

一般使用这个限制导航角色路径的时候会用到


💙分离路面导航(OffMeshLink)

说完了这个分层路面导航,再来说一下这个分离路面导航

分层挺好理解,就是设置不同的路,需要付出不同的代价,那分离又是什么呢?

  • 现实世界中,有时候地形之间会有沟壑,比如一条不宽的小河,并没有桥在上面

  • 那我们怎么过去呢,轻松一跳就过去了,但是如果这条河很宽,那我们就过不去了,需要一座桥才能过去

  • 还有就是一个高台,假设有一米高,那我们还是可以很轻松的一跃而下,那如果换成10米高的呢,想想还是算了叭~

  • 那在虚拟世界中也是同理,我们设置普通的导航网格,如果遇到沟壑和高台,那是过不去的,必须要一个桥梁才能绕过去

  • 那这个分离路面导航就可以成为我们的一座桥梁

这个off mesh links桥梁有两种设置方法,一种是自动设置,一种是手动设置,下面来详细说一下

🚩自动设置off mesh links

还是打开NavigationBake面板

  • Jump Distance :代表可以跳跃沟壑的最大距离
  • Drop Height :代表可以跳跃高台最大高度


设置完了之后,要选中场景中的静态物体,在Object面板勾选这个Generate OffMeshLinks,再重新烘焙即可


默认一般都是勾选的,我这里故意给左边的平台没有勾选这个地方,所以就只能从右边跳过去,左边不能触发跳跃

看一下效果,因为左边的没有勾选Object面板中的Generate OffMeshLinks,所以左边不能跳跃,右边可以!

🚩手动设置off mesh links

这个自动的操作比较简单,只需要设置一下合适的跳跃高度和长度就可以进行分离导航了

那接下来看一下手动怎样设置吧!

我们需要创建两个空对象,添加上off mesh link组件,分别用来控制跳跃的起点终点

如下图所示

off mesh link组件面板属性

  • Cost Override:路径估值,和之前的Area一样
  • Bi Directional:控制跳跃是单向的还是双向的
  • Activated:控制Link是否激活
  • Auto Update Position:自动更新位置,当移动开始结束点的时候,自动更新

设置完之后看一下效果图,在我们设置的起点终点位置就可以随意跳跃了

并且设置了路径估值以后,这一条路线也是化为导航路线中,优先挑选最佳路径进行导航


💜动态路障(Nav Mesh Obstacle)

🚩NavMeshObstacle 组件介绍

Nav Mesh Obstacle导航网格障碍物

  • 在设置导航系统时,我们一般都是将场景中不会发生位置变化的物体设置成静态

  • 如果出现障碍物的话,一般也是设置成静态,参与Navigation的导航烘焙,这样我们角色导航时不会与静态物体发生碰撞

  • 但是如果我们的障碍物不是静态的,是动态的时候,比如我们是通过代码实例化出的一个物体,并没有参与导航烘焙

  • 那这个时候就需要 Nav Mesh Obstalce组件来提供这个功能了!

🚩NavMeshObstacle 面板属性

  • Shape:选择障碍的几何形状
  • Carve:如果勾选,会重新渲染网格.勾选上该属性后,会出现如下三个可以控制的参数
  • Move Threshold:[移动阈值]
    大于该值的移动,才认为是真正发生了移动。
  • Time To Stationary:[时间静止]
    每间隔多长时间,检查一次该障碍物的位置,如果发生了移动则动态的更新导航
    网格的数据
  • Carve Only Stationary:[仅雕刻静止物体]
    勾选后,则按上面的时间间隔,固定的检查位置,固定时长更新网格数据;
    如果不勾选,则是每帧都会检查位置,如果发生位移,立刻更新网格数据。

简单测试一下Carve是否勾选的效果

Carve未勾选时:坚持等路障消除。

  • 就像个憨憨一样,明知道前面有障碍物,还是在这傻等这障碍物消除,有别的路都不走

  • 是不是像极了你追寻爱情时候的样子!

    Carve勾选时:选择另谋出路

  • 既然知道前面的是障碍物,那就要另谋出路,就算右边那条路的代价很高,那我们也需要前行不是

  • 比起傻等的憨憨可是要强多了,天涯何处无芳草,何必单恋一条路!


💬总结

  • 本篇文章对Unity中的Navigation导航系统做了一个全面解析
  • 包括导航网格导航角色分层路面导航分离路面导航动态路障几部分,还是比较容易理解的!
  • Navigation相关的地方应该是都写出来了,并搭配简单的实例效果展示,如果有未说明的地方也可以评论区告诉我哦!

Tips

  • 还是要在这里说一下,写博客的初衷是为了自己记录一些知识内容,也可以分享给需要的人看
  • 虽然现在知识付费已经很常见了,但还是想保持一个知识开源的精神
  • 就像这篇导航文章,写完之后对我个人而言并没有很大的用处,但是对于需要这块知识的人可能就会有所帮助
  • 我希望有需求的人看完之后能够真正学会,那这篇博客的价值就体现出来了
  • 但是一味地付出得不到收获自然很难有坚持下去的动力,所以我也是开了一个专门写Unity制作的小游戏付费专栏
  • 有需求的人自然订阅就好啦,一顿饭钱收获的可不只是几篇文章,更多的收获知识
  • 每当有人告诉我文章写得很好,而且主动把我的文章推给更多人看的时候,就是写文章最大的欣慰了吧!
  • 还是希望自己能保持写博客的初心,我个人的付费文章和专栏是不会设置很多的,所以大家看完文章点个三连就是对我最大的支持啦!

  • 🎄如果感觉文章看完了不过瘾,可以来我的其他 专栏 看一下哦~
  • 🎄比如以下几个专栏:Unity基础知识学习专栏Unity游戏制作专栏Unity实战类项目 算法学习专栏
  • 🎄可以学习更多的关于Unity引擎的相关内容哦!直接点击下面颜色就可以跳转啦!
🚀 优质专栏分享 🚀
🎄 Unity基础知识学习专栏 🎄
⭐️ Unity游戏制作专栏 ⭐️
🍇 Unity实战类项目 🍇
💦 小Y学算法 💦
🚀 优质专栏分享 🚀

以上是关于Unity零基础到入门 ☀️| 万字教程 对 Unity 中的 Navigation导航系统基础 全面解析+实战演练收藏不迷路的主要内容,如果未能解决你的问题,请参考以下文章

Unity零基础到入门☀️| 万字教程 讲解Unity中的数据存储 PlayerPrefsXMLJSON建议收藏

Unity零基础到进阶 ☀️| 近万字教程 对 Unity 中的 动画系统基础 全面解析+实战演练,你确定要错过吗?

❤️Docker超详细基础教程,快速入门docker首选❤️(万字长文建议收藏)

❤️六万字《算法和数据结构》之《画解数据结构》总纲,算法零基础教程❤️(建议收藏)

❤️ 万字Python MySQL从入门到精通详细教程❤️ 再也不用担心学不会数据库了❤️

❤️六万字《算法和数据结构》之《画解数据结构》总纲,算法零基础教程❤️(建议收藏)