Q1:我们在做一个RTS游戏,开始用的是Unity自带的NavMesh的寻路,但发现这个并不适合RTS多人寻路,因为总会出现阻挡和闪跳的问题。看Asset Store上的A* path插件评论说在碰撞上有问题,不知道大家是否能提供比较成熟的解决方案?

我们上一个项目是RTS项目,刚开始寻路问题解决方案过程中遇到过和你相似的疑惑,修改探索和调教了很长时间,分享几点供题主参考下。

先上结论:我们采用了两层结构 A Start Pathfinding Project Pro + Unity NavMesh。

1)主体寻路方案使用 A Start Pathfinding Project Pro 这个插件中传统的网格形式,并进行了深度修改扩展,主要是满足寻路过程的通路性需要考虑到单位半径大小,这样寻路精度高;

2)使用Unity NavMesh系统作为寻路过程中的碰撞系统,因为你说的很对,这个寻路插件的碰撞有问题,稍后解释。

以上两部分组成“寻路算法+精确碰撞”。接下来说下以上方案的原因和细节。

1、NavMesh寻路速度快但不够精确。RTS还是适合使用传统的四方形NavGrid格子寻路,而且现有的任何寻路算法默认都是不支持考虑寻路单位半径大小对寻路过程的影响,但我们策划绝不允许1米宽的缝隙被一个两米宽的胖子挤过去,如果使用Navmesh并且动态生成阻挡会出现寻路路径是有了,可是由于碰撞问题大的单位会卡在缝隙这里来回“发抖”的情况;这个只能自己动手修改,所以我们买了该插件然后自己从里到外修改,具体修改算法原理和修改后的示意图,你可以参考这里:http://www.cnblogs.com/yaukey/p/rts_unit_traverse_size_based_path_finding.html
修改完后,每次寻路会将单位的直径大小当做寻路参数之一传入进行寻路。

使用这个插件开启两个线程左右来寻路是我后来调教出的、一个比较理想的结果。然后是地图中各种单位会出生和死亡,当单位站定不动,需要生成阻挡;移动了需要移除阻挡恢复此处的通路性,通过再修改下插件中的DynamicObscule这个组件(原生功能太简单)来实现;我们具体是每个单位都有一个对应的大小的CapsuleCollider空对象挂上这个脚本,单位站定将该物体放置到单位的位置并激活它,单位移动隐藏该空物体即可,这个脚本会引起地图通路性的更新,这个更新是多线程的,这一点是要注意的,通过回调事件来做响应的事情,切记不要在同一帧或者下一帧去做,因为即时性不能保证。这样就能让整个地图一直根据单位来更新通路性。

2、寻路的通路性问题解决了,现在来解决碰撞问题。这个插件自带了碰撞算法,使用的rvo算法,但是据我当初各种调教实验,它的碰撞都达不到我们的要求,单位多了拥挤的时候总是会有些单位站立后变得重叠了,最不能接受的是两个单位完全重叠。在这里我花了相当多的时间都不能修改出的满意的效果。后来想起来recastnavigation作者亲口说过虽然Unity的NavMesh基于此,但是Detour系统经过深度的改写,Detour包含了巡航和碰撞,而实际使用也发现NavMeshAgent之间的碰撞是很精确的,于是我想了个取巧的办法,给地表再铺一层跟AStar插件的寻路面积一样大的NavMesh,但是没有任何的阻挡(理解为一片纯蓝色),同时给寻路单位添加一个NavMeshAgent,然而这个东西只用它的碰撞,而不使用寻路(没有阻挡,任何寻路都是两点直线,可以考虑几乎无开销),这样最后实际的碰撞效果才算达到我们满意的效果。

以上就是我所说的两层含义,我再说下坑和问题。

1)当初开发Unity版本是Unity
5.3.7-5.3.8,插件版本5.x,寻路插件中底层会有Physics.CheckCapsule调用,但是多线程大量调用,会导致底层PhysX物理引擎崩溃,游戏闪退,不必现但是大量的话很容易一下就挂,插件官方论坛也有这个Bug讨论,后来我将此换成了两个
Physics.CheckSphere 调用,目前2017版本没有测试过;

2)我在1中使用的方法,在UWA性能评测中,每次都是Dynamic Collider超标,这个需要自己取舍了,但是总体我们游戏的瓶颈不在寻路一块,消耗在这些测试中看来比较理想;

3)插件中由于是多线程更新,有很多的完成事件回调,基本都是利用这些链接游戏系统中,不够了自己加,否则依然是容易在未更新完成时得到错误的结果;

4)有可能的话再优化下内部的一些堆内存分配,并且和游戏系统结合后注意释放和断开引用,否则容易内存泄漏,造成寻路插件被引用以至于后面引用很长一串对象都不得释放;

5)寻路精度和碰撞精度在游戏中的表现,需要花比较多的时间去调教参数,有时候表现不好未必是方案不好,然后如果你们对实时同步性要求较高,这个方案还必须再进一步完善和扩展下。

我们使用这个寻路方案的项目是:《战地指挥官》,你可以下载看看寻路是否符合你的要求,苹果安卓各平台都有。以上是我暂时想起来的一些心得,希望对题主有所帮助:)

感谢Yaukey@UWA问答社区提供了回答,欢迎大家转至社区进行进一步交流:

https://answer.uwa4d.com/question/5ad0553b910222635366dd34

如何制作RTS游戏的寻路系统?的更多相关文章

  1. Atitit 游戏引擎---物理系统(1)------爆炸效果

    Atitit 游戏引擎---物理系统(1)------爆炸效果 1.1. 动画框架的来源flex,jqueryuijs,anim , cocos2d 1 1.2. Jqueryui的特效库 1 1.3 ...

  2. Unity3D RTS游戏中帧同步实现

    帧同步技术是早期RTS游戏常用的一种同步技术,本篇文章要给大家介绍的是RTX游戏中帧同步实现,帧同步是一种前后端数据同步的方式,一般应用于对实时性要求很高的网络游戏,想要了解更多帧同步的知识,继续往下 ...

  3. Unity3D学习笔记(十五):寻路系统

    动画生硬切换:animation.play();//极少使用,常用融合方法 动画融合淡入:animation.CrossFade(“Idle”, 0.2f);//0.2f为与前一动画的融合百分比为20 ...

  4. Spine应用--使用Spine动画制作动作游戏

    在前面的文章中,已经陆陆续续的讲解了一些使用Spine动画的细节,有了这些细节,我们已经满足了在unity中使用Spine动画制作动作游戏的技术基础. 那么,要使用Spine动画在unity中制作一款 ...

  5. 使用CocosSharp制作一个游戏 - CocosSharp中文教程

    注:本教程翻译自官方<Walkthrough - Building a game with CocosSharp>,官方教程有很多地方说的不够详细,或者代码不全,导致无法继续,本人在看了G ...

  6. Cocos2d-x v3.6制作射箭游戏(二)

    原文 Cocos2d-x v3.6制作射箭游戏(二) 六 24, 2015by RENSHANin COCOS2D-X 上章我们创建并加载了游戏地图,接下来的两章我们将实现如下的效果. 在开始之前,先 ...

  7. 制作OpenStack用的RHEL7系统镜像

    制作OpenStack使用的RHEL7系统镜像,并进行相关设置,安装XRDP以进行远程访问. 1.在KVM中安装RHEL7.2客户机: 2.设置网卡为dhcp并onboot=yes,使得虚拟机能自动获 ...

  8. [Mugeda HTML5技术教程之14]案例分析:制作网页游戏

    本文档要分析的案例是一个爱消除的网页小游戏,从中可以体会一些Mugeda API的用法和使用Mugeda动画制作网页游戏的方法. (一)游戏规则: 1.开始游戏时,手机出现在最上面一行的任意一格: 2 ...

  9. 制作macOS10.12系列的系统镜像文件

    制作macOS10.12系列的系统镜像文件步骤,过程也比较简单,十来个命令.以10.12.6为例,首先,在苹果商店下载系统安装包APP,或者网上下载后把安装APP复制到  应用程序  文件夹. 然后打 ...

随机推荐

  1. Order By 问题集合

    问题(一):Order By 多个参数排序 在做多字段的排序的时候我们经常会会用到该语句. 所以多参数排序是从左到右的局部排序,修改的范围只有前面参数(几个参数)相同的情况下在排序. select * ...

  2. 10款好用的 jQuery 图片切换效果插件

    jQuery 是一个非常优秀的 Javascript 框架,使用简单灵活,同时还有许多成熟的插件可供选择.其中,最令人印象深刻的应用之一就是对图片的处理,它可以让帮助你在你的项目中加入一些让人惊叹的效 ...

  3. 《JavaScript 实战》:JavaScript 图片滑动切换效果

    看到alibaba的一个图片切换效果,感觉不错,想拿来用用.但代码一大堆的,看着昏,还是自己来吧.由于有了做图片滑动展示效果的经验,做这个就容易得多了. 效果预览 仿淘宝/alibaba图片切换: 默 ...

  4. 使用Docker 快速搭建nuget本地服务器,Hosting private nuget server using docker in seconds!

    Server #below line automatically creates the folder, mount the volumes and maps the ports. docker ru ...

  5. js刷题:leecode 25

    原题:https://leetcode.com/problems/reverse-nodes-in-k-group/ 题意就是给你一个有序链表.如1->2->3->4->5,还 ...

  6. jQuery.pin.js笔记

    jQuery.pin.js是一个把元素钉在页面上某个位置的插件,它能够将某个元素一直挂在一个固定的位置而不论滚动条是否滚动. 特点: 1. 可以钉住一个元素,主要作用就是滚动超出的时候不会隐藏而是一直 ...

  7. tf.name_scope tf.variable_scope学习

    1. 首先看看比较简单的 tf.name_scope(‘scope_name’). tf.name_scope 主要结合 tf.Variable() 来使用,方便参数命名管理. ''' Signatu ...

  8. linux 实现自动创建ftp用户并创建文件夹

    创建一个 createuser.sh的脚本文件 #!/bin/sh #传入的文件名 name=$1 #创建该用户所对应的ftp文件夹   /srv/ftp是我的ftp服务器的根目录 mkdir /sr ...

  9. LNMP结合discuz的配置

    一.安装discuz 配置参照LAMP结合discuz的第一部分 不要忘记了 添加hosts~!!!! ===============我是分割线.========================== ...

  10. C++——stoi函数

    版权声明:本文系原创,转载请声明出处. 1. 函数原型 , ); , ); 2. 参数说明 str String object with the representation of an integr ...