动态生成navmeshi-进击的新版NavMesh系统:看我飞檐走壁
| http://forum.china.unity3d.com/thread-25421-1-1.html 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来获取这些新的功能:
需要注意的是,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: |
动态生成navmeshi-进击的新版NavMesh系统:看我飞檐走壁的更多相关文章
- 进击的新版NavMesh系统:看我飞檐走壁
0x00 前言 unity5.6作为Unity5最后的一个版本,的确起到了一个承上启下的作用.除了上一篇文章<进击的AssetBundles和它的工具们>中提到的AssetBundles- ...
- NavMesh系统动态碰撞的探讨
Unity3D提供的NavMesh系统可以方便的解决游戏的寻路问题,但是该系统有一个比较让人不理解的问题: NavMesh导航时会忽略Physics系统本身的碰撞,也就是说NavMeshAgent在移 ...
- 动态生成能够局部刷新的验证码【AJAX技术】---看了不懂赔你钱
在开发JavaWeb应用时,动态生成能够局部刷新的验证码是一项必须的功能,在这里我们将会详细的讲解如何实现这一功能. 一.涉及技术 该功能需要用到AJAX异步传输技术,这样能保证在点击"看不 ...
- 如何安装nginx_lua_module模块,升级nginx,nginx-lua-fastdfs-GraphicsMagick动态生成缩略图,实现图片自动裁剪缩放
如何安装nginx_lua_module模块,升级nginx,nginx-lua-fastdfs-GraphicsMagick动态生成缩略图,实现图片自动裁剪缩放 参考网站:nginx-lua-fas ...
- 分享我基于NPOI+ExcelReport实现的导入与导出EXCEL类库:ExcelUtility (续3篇-导出时动态生成多Sheet EXCEL)
ExcelUtility 类库经过我(梦在旅途)近期不断的优化与新增功能,现已基本趋向稳定,功能上也基本可以满足绝大部份的EXCEL导出需求,该类库已在我们公司大型ERP系统全面使用,效果不错,今天应 ...
- Jquery.Qrcode在客户端动态生成二维码并添加自定义Logo
0 Jquery.Qrcode简介 Jquery.Qrcode.js是一个在浏览器端基于Jquery动态生成二维码的插件,支持Canvas和Table两种渲染方式,它的优点是在客户端动态生成,减轻了服 ...
- MVC5+EF6 入门完整教程13 -- 动态生成多级菜单
稍微有一定复杂性的系统,多级菜单都是一个必备组件. 本篇专题讲述如何生成动态多级菜单的通用做法. 我们不用任何第三方的组件,完全自己构建灵活通用的多级菜单. 需要达成的效果:容易复用,可以根据mode ...
- CGI实现页面的动态生成
传统的Web应用开发局限于有限的静态页面(HTML静态页面),不利于系统的扩展,不能提供及时信息,而且修改维护麻烦,所以建立一个动态Web应用程序尤为重要.一方面根据访问者的不同请求返回不同的访问信息 ...
- Java 动态生成 PDF 文件
每片文章前来首小诗: 今日夕阳伴薄雾,印着雪墙笑开颜.我心仿佛出窗前,浮在半腰望西天. --泥沙砖瓦浆木匠 需求: 项目里面有需要java动态生成 PDF 文件,提供下载.今天我找了下有关了,系 ...
随机推荐
- iOS 使用GitHub托管代码
1.注册一个github账号在官网.https://github.com/github 2.下载mac版的github客户端.网址:https://desktop.github.com 3.之后会在出 ...
- PAT天梯赛 L2-020. 功夫传人 【DFS】
题目链接 https://www.patest.cn/contests/gplt/L2-020 思路 从师父开始 一层一层往下搜 然后 搜到 得道者 就更新答案 AC代码 #include <c ...
- Git查看并修改name和email
显示name的方法: git config user.name git config --list 或者查看~/.gitconfig文件. 改名字: git config --global user. ...
- lk进kernel
-- ] [upmu_is_chr_det] [] DRAM Rank : [] DRAM Rank[] Start = 0x40000000, Size = 0x25fc0000 [] DRAM R ...
- HTML/CSS实现的搜索框
谷歌和百度首页的搜索框都是<input>+<button>模式的,bing的搜索框感觉要好点儿.简言之,就是将提交按钮放到<input>中,其实这是做不到的,只能伪 ...
- 在eclipse配置Maven
一.配置系统Maven环境变量 1. 前往https://maven.apache.org/download.cgi下载最新版的Maven程序: 2. 新建环境变量MAVEN_HOME,赋值D: ...
- Linux网络编程 gethostbyaddr()
C语言函数 概述: 返回对应于给定地址的主机信息. #include <winsock.h> struct hostent FAR *PASCAL FAR gethostbyaddr(co ...
- BZOJ4836: [Lydsy1704月赛]二元运算
BZOJ4836: [Lydsy1704月赛]二元运算 https://lydsy.com/JudgeOnline/problem.php?id=4836 分析: 分开做,维护两个桶. 分治每次求\( ...
- 「UVA557」 Burger(概率
本题征求翻译.如果你能提供翻译或者题意简述,请 提交翻译 ,感谢你的贡献. 题目描述 PDF 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 复制 3 6 10 256 输出样例# ...
- 【LeetCode】016 3Sum Closest
题目: Given an array S of n integers, find three integers in S such that the sum is closest to a given ...










