如何在游戏中使用Unity做寻路导航
近日,一位海外开发者在博客中分享了自己用Unity engine重做之前开发的Flash游戏寻路导航的经验,希望能给大家带来帮助:
大家好。最近一直在忙着用Unity engine重做一个06年的Flash游戏。虽然我们已经在“抵达地狱”这个项目上工作了一年多,但是我希望在这里从零开始写一篇开发者博客,因为这样会给读者一个更完整的印象。
如果你不熟悉这个游戏,我想在这里说几句。我们正在重做一个由我的朋友Eduardo Mojica和Richard Rout在2006年开发的Flash游戏。这是一个点击冒险游戏,我们将用Unity引擎重做它。我做游戏编程开发大概十年了,但这是我用Unity engine做的第一个游戏。
在说别的之前,我首先要说的是玩家角色的动作。因为这个游戏现在是在真实的3D中,玩家角色需要在3D空间中找到他的路。幸运的是,Unity引擎已经有一些很好的内置寻路功能。你只需要打开窗口——导航,选择你要用的对象放入路径中,然后标记为‘导航静态)’,这会告诉Unity这些对象是静态的(不移动),在寻路的时候要考虑进去。
将对象设置为“静态导航”
这里我想说说这个功能有多强大。以前我和大多数游戏开发者一样,都要自己搭建寻路系统。我之前做过一个A*tile和一个基于节点的寻路系统。在两种情况下,特别是基于节点系统的寻路生成的墙是非常令人头痛的。在基于节点的寻路系统中,你必须手动在它们之间导航AI使用的点。Unity不仅有导航功能,还使用了导航网格,比手动放置节点效率更高,更流畅。更重要的是,你可以一键重新计算整个导航网格,彻底摆脱手动修改导航节点的做法。
我用基于节点的系统做的一个失败的寻路系统。
将静态对象添加到导航网格后,您可以选择一系列设置,然后单击烘焙按钮,例如在考虑添加墙之前,确定坡度有多陡以及台阶应该有多高。所以你可以得到一个预览视图。值得注意的一点是,场景中存在一个对象并不意味着它是导航网格的一部分。比如这个游戏,我不在乎玩家会不会踩到碎石,所以没有把任何碎石标记为导航静态,加快了网格的生成速度。
《抵达地狱》其实是有数值的。
导航网格生成后,我简单地向播放器模型添加了一个NavMeshAgent组件。现在游戏可以找到自己的路了,唯一剩下的就是添加鼠标输入来控制NavMeshAgent的目的地。
NavMesh制成的烘焙
NavMeshAgent设置
为了告诉NavMeshAgent导航,我做了以下说明:
1.注意鼠标输入
2.将鼠标放在屏幕空间中
3.把屏幕空间变成相机发出的一束光。
4.当光线到达地面时移开
5.将NavMeshAgent的目的地设置为地板上的相应位置。
C#代码是这样的:
可视化视图中的目的地和路径
这解决了我游戏的大部分导航需求,除了当游戏中的一些活动导致导航网格改变的时候。例如,第一个房间中的孩子起初是关闭的,然后当它打开时,当行网格需要更新以反映这种变化时,允许玩家走过新打开的孩子。我在游戏运行的时候没有使用rebake完整的静态导航网格,而是使用了navmesh障碍物组件,可以让你在寻路的过程中添加动态物体。如果物体移动,Unity的寻路算法会根据实际情况进行更新。
导航路径会根据navmesh障碍物的变化自动改变。
视觉视图
所以做了游戏寻路导航,这是游戏《抵达地狱》中的导航工作原理,只有Unity自带的导航功能才能完成。