0x00 前言

unity5.6作为Unity5最后的一个版本,的确起到了一个承上启下的作用。除了上一篇文章《进击的AssetBundles和它的工具们》中提到的AssetBundles-Browser,本文还会介绍另一个在Github开源的,用于Unity5.6+的新寻路功能。

0x01 曾经的痛点

Unity5.6之前的navmesh系统的确操作起来十分容易上手,门槛很低。我们只需要将场景内需要烘焙navmesh的区域勾选上Navigation Static选项,之后就可以在Navigation窗口中烘焙整个场景了。

但是曾经的navmesh系统却也存在着一些性能上的和使用场景上的缺陷。

一个常见的问题,由于要预先烘焙场景的navmesh,因此我们很难方便的在运行时动态的修改navmesh。更不用说,有一些游戏的场景并非提前制作好的,需要在运行时动态的生成,这种情况下就无法使用navmesh了。

另一个问题是,如果场景过大的话,烘焙之后的navmesh也会保存很多数据,在运行时会造成一些内存上的开销。

当然,抛开这些不谈,另外一个让我吐槽navmesh的一点就是,它竟然不支持垂直面的导航。

在做一些2d的platform游戏时,我很希望能利用navmesh来实现寻路的逻辑。(图文无关)

但是,不幸的是,之前的navmesh是不支持的。

0x02 组件化的navmesh

不过还好,虽然新的navmesh系统并没有随着unity的正式版本一同发布。但是,我们还是可以通过github来获取这些新的功能:

NavMeshComponents

需要注意的是,Unity的版本要求在5.6以上。

我们可以看到,其实这里只有4个高层的C#脚本文件:



利用这4个脚本文件,就能基本解决我们之前的烦恼了。

其中NavMeshSurface这个脚本将navmesh组件化,利用这个组件就可以很方便的烘焙挂载该组件的对象的navmesh信息,而无需打开一个navigation窗口对整个场景进行烘焙了。我们甚至可以将挂载这个脚本的GameObject烘焙后保存为一个prefab,这个带有navmesh信息的prefab跟其他的prefab一样。



为对象添加NavMeshSurface组件很简单。在这里我们可以看到和之前navigation窗口类似一些设置,但是请注意,这里已经不是整个场景烘焙了。navmesh已经组件化了,它只会烘焙挂载它的对象。

只要点击一下这个组件下的Bake按钮,挂载它的对象就被烘焙好了。

那么GameObject能否挂载多个NavMeshSurface组件呢?这一种需求也的确存在,例如怪物和玩家的寻路策略不同,有些地方玩家能通过而怪物却不能通过。

这的确也是可以的,同一个GameObject能够同时挂载多个NavMeshSurface组件,并且烘焙不同的navmesh供不同的角色使用。

这样,我们针对不同的角色的NavMeshAgent组件设置不同的agent type并和烘焙好的两个navmesh匹配好就可以了。

0x03 飞檐走壁

好了,借助NavMeshSurface组件我们实现了navmesh的组件化。那么是不是我们就能很方便的实现在垂直面上烘焙navmesh了呢?各位想想我们是否能很轻松的让一个游戏对象的角度改变呢?答案是是的。那么这个游戏对象上如果有navmesh信息的话,我们只需要把这个游戏对象从水平变为垂直是否就行了呢?是的。

因此实现游戏角色的在垂直面上飞檐走壁的功能就变得十分简单了。



当然了,在水平面的navmesh和垂直面的navmesh之间我们还会用到NavMeshLink这个组件来链接二者。各位自己在实践的时候需要留意一下这一点。

0x04 在运行时烘焙navmesh

接下来就让我们看看新的navmesh系统带给我们的新的惊喜——在运行时烘焙navmesh。

这是一个很现实的需求,例如一些动态生成场景的游戏,我们无法在一开始就确定这个场景到底是什么样子的,所以也无法使用之前的navmesh系统,因为以前的navmesh只能在editor内烘焙。但是现在我们使用新的navmesh系统就能够很方便的在运行时烘焙navmesh了。



如图,这是一个空场景,在游戏运行之后场景才生成出来场景内的各种道路,此时单击鼠标,navmesh就生成了。

其实在新的navmesh系统内,实现这个机制十分简单。只需要调用游戏对象上挂的NavMeshSurface组件的BuildNavMesh()方法。

void Start()
{
surface = GetComponent<NavMeshSurface>();
} void Update()
{
if (Input.GetMouseButtonDown(0))
{
surface.BuildNavMesh ();
}
}

既然navmesh已经可以在运行时创建了,那么我们能否也在运行时实例化一个navmesh的prefab,实时的影响场景内的寻路策略呢?

答案是当然可以。

0x05 场景太大不用愁

自己做过寻路算法的童靴可能会意识到一个问题,就是在做寻路时如果场景过大的话,寻路的数据可能会比较消耗内存。同样在navmesh中,如果场景过大,或者玩家的视野范围有限,一些对玩家当前位置影响不大的场景的其他位置的navmesh数据就有可能造成一些无谓的消耗。

在新的navmesh系统中,我们同样可以优化这个问题,只烘焙玩家周围的navmesh。



这里同样需要NavMeshSurface组件,在inspector视窗我们可以选择collect object中的volume,之后设定size的值就可以值烘焙这个范围内的navmesh了。之后随着玩家的移动,再动态烘焙新的navmesh就可以了。

ref:

【1】High-level NavMesh Building Components

【2】Unite Europe 2017 - Finding the path: New navigation features

各位如果觉得有趣的话,欢迎点个赞。

-EOF-

最后打个广告,欢迎支持我的书《Unity 3D脚本编程》



欢迎大家关注我的公众号慕容的游戏编程:chenjd01

进击的新版NavMesh系统:看我飞檐走壁的更多相关文章

  1. 动态生成navmeshi-进击的新版NavMesh系统:看我飞檐走壁

    http://forum.china.unity3d.com/thread-25421-1-1.html0x00 前言 unity5.6作为Unity5最后的一个版本,的确起到了一个承上启下的作用.除 ...

  2. NavMesh系统动态碰撞的探讨

    Unity3D提供的NavMesh系统可以方便的解决游戏的寻路问题,但是该系统有一个比较让人不理解的问题: NavMesh导航时会忽略Physics系统本身的碰撞,也就是说NavMeshAgent在移 ...

  3. linux驱动程序之电源管理之新版linux系统设备架构中关于电源管理方式的变更

    新版linux系统设备架构中关于电源管理方式的变更 based on linux-2.6.32 一.设备模型各数据结构中电源管理的部分 linux的设备模型通过诸多结构体来联合描述,如struct d ...

  4. 新版raspbian系统的固定IP配置和启用root账户的ssh登录功能的方法

    1. 2016新版raspbian系统的固定IP配置: 自2016年2月份新版raspbian系统发布以后,树莓派的固定IP配置方法就与之前不一样了. 之前在raspbian系统中编辑/etc/net ...

  5. 如何下载官网最新版 win10 系统?

    如何下载官网最新版 win10 系统?步骤: 一. 下载 遨游浏览器 将UA切换成,手机访问:推荐 UC浏览器,UA设置: Mozilla/5.0 (Linux; U; Android 8.0.0; ...

  6. [原]Unity3D深入浅出 - 新版动画系统(Mecanim)

    Mecanim概述: Mecanim是Unity提供第一个丰富而复杂的动画系统,提供了: 针对人形角色的简易的工作流和动画创建能力 Retargeting(运动重定向)功能,即把动画从一个角色模型应用 ...

  7. bios下能看到硬盘,进入系统看不到的解决方法

    新加了个固态硬盘 安装完系统后,打开我的电脑 看不到老硬盘的分区,进入磁盘管理也看不到. 最后,重启 选择老硬盘进入系统后, 再重启,进入新硬盘的系统, 就显示出来了

  8. 我不是机器人:谷歌最新版验证码系统ReCaptcha破解已开源

    选自 Github 作者:George Hughey 机器之心编译 每个人都讨厌验证码,这些恼人的图片中包含你必须输入的字符,我们只有正确地填写才能继续访问网站.验证码旨在确认访问者是人还是程序,并防 ...

  9. 树莓派3B新版raspbian系统换国内源

    树莓派新版系统更换了专门优化过的桌面环境PIXEL,正好手头有个闲置的TF卡决定刷上新版系统玩玩.下载刷系统过程很多教程页很简单.插卡,上电开机,释放卡上的剩余空间都很正常,因为树莓派官方源访问很慢下 ...

随机推荐

  1. 关于STM32 IAP

    转眼间天亮了...... 然后就想起了一个朋友QQ的个性签名:年轻人总是要为一些自己认为有意义的事情而废寝忘食,通宵达旦,直至白发方休........ 对了这篇文章一定会介绍的很详细,请细嚼慢咽... ...

  2. 【JAVAWEB学习笔记】网上商城实战2:异步加载分类、Redis缓存分类和显示商品

    网上商城实战2 今日任务 完成分类模块的功能 完成商品模块的功能 1.1      分类模块的功能: 1.1.1    查询分类的功能: 1.1.2    查询分类的代码实现: 1.1.2.1  创建 ...

  3. Javaweb---如何使用eclipse创建Javaweb项目

    在配置好--服务器Tomcat与Eclipse后,进行项目创建 配置地址:http://blog.csdn.net/baidu_37107022/article/details/71405194 流程 ...

  4. javaSE_07Java中类和对象-封装特性

    一.谈谈什么是面向对象的思维 理解面向对象,重点是要思考以下的问题 面向过程 vs 面向对象 Ø 谈谈什么是面向过程的编程思想? Ø 为什么有面向过程还要有面向对象? Ø 谈谈什么是面向对象的编程思想 ...

  5. 以往CSDN博文目录

    专栏一 原生javascript(3篇) 1. javascript立即执行函数详解 http://blog.csdn.net/faith1460/article/details/71600770 2 ...

  6. Vue爬坑之vuex初识

    在 Vue.js 的项目中,如果项目结构简单, 父子组件之间的数据传递可以使用  props 或者 $emit 等方式 http://www.cnblogs.com/wisewrong/p/62660 ...

  7. Python:一篇文章掌握Numpy的基本用法

    前言 Numpy是一个开源的Python科学计算库,它是python科学计算库的基础库,许多其他著名的科学计算库如Pandas,Scikit-learn等都要用到Numpy库的一些功能. 本文主要内容 ...

  8. springmvc 之 深入核心研究

    一.前言:二.核心类与接口:三.核心流程图四.DispatcherServlet说明五.双亲上下文的说明六.springMVC-mvc.xml 配置文件片段讲解 七.如何访问到静态的文件,如jpg,j ...

  9. Ext 创建workspace package

    Ext 创建workspace package Package ExtJs Project 1. 创建工作区间文件目录 md wpt 2. 进入目录 cd wpt 3. 创建 创建工作区间 sench ...

  10. URLConnection调用接口

    写在前面: 项目是java web,jdk1.4,weblogic 7;对方.net系统,用wcf开发的接口.对方提供接口url地址,以及说明用post方式去调用,无需传递参数,直接返回json ar ...