如何制作RTS游戏的寻路系统?

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游戏的寻路系统?的更多相关文章
- Atitit 游戏引擎---物理系统(1)------爆炸效果
Atitit 游戏引擎---物理系统(1)------爆炸效果 1.1. 动画框架的来源flex,jqueryuijs,anim , cocos2d 1 1.2. Jqueryui的特效库 1 1.3 ...
- Unity3D RTS游戏中帧同步实现
帧同步技术是早期RTS游戏常用的一种同步技术,本篇文章要给大家介绍的是RTX游戏中帧同步实现,帧同步是一种前后端数据同步的方式,一般应用于对实时性要求很高的网络游戏,想要了解更多帧同步的知识,继续往下 ...
- Unity3D学习笔记(十五):寻路系统
动画生硬切换:animation.play();//极少使用,常用融合方法 动画融合淡入:animation.CrossFade(“Idle”, 0.2f);//0.2f为与前一动画的融合百分比为20 ...
- Spine应用--使用Spine动画制作动作游戏
在前面的文章中,已经陆陆续续的讲解了一些使用Spine动画的细节,有了这些细节,我们已经满足了在unity中使用Spine动画制作动作游戏的技术基础. 那么,要使用Spine动画在unity中制作一款 ...
- 使用CocosSharp制作一个游戏 - CocosSharp中文教程
注:本教程翻译自官方<Walkthrough - Building a game with CocosSharp>,官方教程有很多地方说的不够详细,或者代码不全,导致无法继续,本人在看了G ...
- Cocos2d-x v3.6制作射箭游戏(二)
原文 Cocos2d-x v3.6制作射箭游戏(二) 六 24, 2015by RENSHANin COCOS2D-X 上章我们创建并加载了游戏地图,接下来的两章我们将实现如下的效果. 在开始之前,先 ...
- 制作OpenStack用的RHEL7系统镜像
制作OpenStack使用的RHEL7系统镜像,并进行相关设置,安装XRDP以进行远程访问. 1.在KVM中安装RHEL7.2客户机: 2.设置网卡为dhcp并onboot=yes,使得虚拟机能自动获 ...
- [Mugeda HTML5技术教程之14]案例分析:制作网页游戏
本文档要分析的案例是一个爱消除的网页小游戏,从中可以体会一些Mugeda API的用法和使用Mugeda动画制作网页游戏的方法. (一)游戏规则: 1.开始游戏时,手机出现在最上面一行的任意一格: 2 ...
- 制作macOS10.12系列的系统镜像文件
制作macOS10.12系列的系统镜像文件步骤,过程也比较简单,十来个命令.以10.12.6为例,首先,在苹果商店下载系统安装包APP,或者网上下载后把安装APP复制到 应用程序 文件夹. 然后打 ...
随机推荐
- JVM调优总结(3):垃圾回收面临的问题
如何区分垃圾 上面说到的“引用计数”法,通过统计控制生成对象和删除对象时的引用数来判断.垃圾回收程序收集计数为0的对象即可.但是这种方法无法解决循环引用.所以,后来实现的垃圾判断算法中,都是从程序运行 ...
- 动态内容的缓存技术:CSI vs SSI vs ESI
CDN 中动态内容是不太好解决的,通常需要很麻烦的技术和方法来实现这些功能,比如我设计过一种动态缓存的方法,基于 session 栏接,然后根据热点来做动态缓存时间的控制.目前开放的实现 Cache ...
- 简易安装sqoop
版本 :hive-0.13.1-cdh5.3.6.tar.gz 1:解压 然后 进到 conf 目录 修改 sqoop-env.sh 2:如果使用mysql 数据库 要将 mysql驱动包拷贝到 ...
- linux中的计算【转】
shell中的赋值和操作默认都是字符串处理,在此记下shell中进行数学运算的几个特殊方法,以后用到的时候可以来看,呵呵 1.错误方法举例 a) var=1+1 echo $var 输出的结果是1+1 ...
- elasticsearch集群介绍及优化【转】
elasticsearch用于构建高可用和可扩展的系统.扩展的方式可以是购买更好的服务器(纵向扩展)或者购买更多的服务器(横向扩展),Elasticsearch能从更强大的硬件中获得更好的性能,但是纵 ...
- 191.Number of 1Bits---位运算---《剑指offer》10
题目链接:https://leetcode.com/problems/number-of-1-bits/description/ 题目大意:与338题类似,求解某个无符号32位整数的二进制表示的1的个 ...
- 用C++写程序的一些感悟
前言 近期使用C++有了一些心得很感悟,这里整理一下. 心得1 如果只会使用LabVIEW写程序,还想要进一步深入程序设计,一定要学习一门文本语言. 什么是会用LabVIEW 会用是个比较笼统的概念. ...
- web deploy 安装失败解决
单独运行安装包,提示脚本运行失败. VS安装提示解包失败. 解决:检查Windows Management Instrumentation服务状态.需要非禁用.
- Python语言库pyttsx3
这是一个文字转语音的python模块. 1. macos下安装的时候出现问题: 后来发现,Foundation, AppKit, PyObjCTools都不存在,主要原因是缺少依赖模块pyobjc, ...
- Transport failed: java.io.EOFException
ActiveMQ服务端有时会报Transport failed: java.io.EOFException这样的错误,这是由客户端丢失连接并反复尝试连接导致的,不是什么大问题,有时网络波动就会产生这种 ...