关于Unity中AI随机巡逻障碍物预判与快速运动时物理穿透的思考
如果不想用Unity的导航系统,很多时候就要解决如何预判前进路径中的障碍物问题,之前也看过一些非常经典的寻路算法例如AStar寻路,虽然也可实现功能,但总感觉有些小题大做。寻路算法大多数都是为了得出最优解,但如果只是用在一个区域内随机运动的远程怪身上的话,根本就不需要用这么复杂的算法。

就比如上面这个简单的远程怪,它根本就不想接近玩家,它的运动方式就是在一定的距离内朝任意方向走一段,到达了就朝玩家来一发,然后就这么反复,直到它被打死。(哎,这悲伤的命运)
然后问题就出现了,因为它就这么呆萌呆萌地一直朝选定的下一个随机位置运动,那么很可能在途中遭遇不可逾越的障碍物,假如这怪物能跳的话那还好说,碰到了障碍物就飞奔而起,来个360度空中转体3周半,惊艳全场。可惜的是它并又没有Get这个技能,所以你就会看到一个顶着障碍物干瞪眼的家伙与障碍物进行着永无天日的持久抗争,于心不忍的你开始给它增加一些预判障碍物的方法:
1.最简单最粗暴,能不能直接用时间来呢,一段时间内还没有任何的距离运动,那说明遇到障碍物了,直接就洗脑重新随机下一个目标位置,如果随机的下一个位置又有障碍物,那就继续,直到可以继续运动为止。其实这里更优的做法应该是进行学习,每次随机到障碍物位置后就记下来,以后周围半径1的范围内都不再成为下一个随机点。
public override TaskStatus OnUpdate()
{
if (timer > .2f)
{
if ((transform.position - posAtlastTimer).sqrMagnitude < .1f)
{
//记录当前位置...
//重新随机目标位置...
}
timer = 0f;
posAtlastTimer = transform.position;
}
}
需要一个计时器timer和记录目标上一timer位置的变量posAtlastTimer。
2.考虑利用OnCollisionEnter(Collision collision)方法来检测,判断碰到的碰撞体的标签,如果是障碍物,就记录当前位置并重新随机。这种方式可以避免因为反复随机到障碍物位置而产生的卡顿问题。
public override void OnCollisionEnter(Collision collision)
{
if (collision.transform.tag == "Collider")
{
//记录当前位置...
//重新随机目标位置...
}
}
3.在每次随机运动前就进行射线检测,发出一条从当前点到目标点方向的射线(也可以按照物体的上下左右边缘发出多条),射线的长度即为当前位置到目标位置的距离,如果射线碰到了障碍物,那么就可以提前得知该路径是无效的。
private Vector3 RayCheckCollider(Vector3 tarPos)
{
Vector3 offset = tarPos - transform.position;
Ray ray = new Ray(transform.position, offset);
RaycastHit info;
if (Physics.Raycast(ray, out info, offset.magnitude))
{
if (info.collider.tag == "Collider")
{
//记录当前位置...
//重新随机目标位置...
tarPos = RayCheckCollider(tarPos);//递归检测
}
}
Debug.DrawLine(ray.origin, tarPos,Color.red);
return tarPos;
}
以上三种方法并不冲突,可同时使用。一般第三种方法要优于前两种,它可以提前避免遭遇障碍物,但往往这样做也缺乏了一定的真实性,可以额外设置一个视野范围进行优化,判断AI是否能提前察觉障碍物,此时发出的射线长度也应该是该视野半径值,一旦AI在行进目标位置的过程中发现障碍物,不等碰到障碍物之前就重新随机下一个目标位置。
AI通过学习记录的无效目标位置集合可用于每次随机出下一目标位置的判定依据,该集合点可设定为所有AI进行随机判定的全局变量。
private void CheckDeadZone(Vector3 tarPos)
{
foreach(var item in deadPoints)
{
if ((item - tarPos).sqrMagnitude < 1f)
{
//重新随机目标位置...
return;
}
}
}
后来发现在遇到快速运动的物体的物理穿透问题时也可以用到射线检测作为预判,在快要到达障碍物时脱离当前运动状态或将速度迅速降低,可有效解决物理穿透的问题。
关于Unity中AI随机巡逻障碍物预判与快速运动时物理穿透的思考的更多相关文章
- 解决Unity中模型部件的MeshCollider不随动画一起运动的问题
Unity的3d游戏开发中,经常遇到需要将模型的某一部分(比如武器),单独做碰撞处理的情况. 导入模型后,给武器部分添加MeshCollider,MeshCollider的Mesh通常包含在模型里,如 ...
- Unity中各个平台的预编译的运用方式
1,unity中官方文档的一个操纵关键词 Platform Dependent Compilation 2,常用的预编译关键词 UNITY_EDITOR 编辑器调用.UNITY_STA ...
- Unity中List的随机排序(乱序)
为什么要给List排序做一个Unity限定条件呢 首先,是C#中的List泛型,若是Java,直接调用Collection.shuffle()就OK了 而Unity的C#版本较低,不能使用Random ...
- Unity中的协程(一)
这篇文章很不错的问题,推荐阅读英文原版: Introduction to Coroutines Scripting with Coroutines 这篇文章转自:http://blog.csdn. ...
- Unity Rain Ai 插件基本使用(二)
前言 在前面的教程中我们已经基本实现了路径导航和障碍物规避. 但是这样我们并没有让我们的角色学会思考,他只是机械的去完成一些步骤,这并不能体现Rain插件的智能. 一个角色他应该有多个不同的状态,待机 ...
- 在Unity中创建攻击Slot系统
http://www.manew.com/thread-109310-1-1.html 马上注册,结交更多好友,享用更多功能,让你轻松玩转社区. 您需要 登录 才可以下载或查看,没有帐号?注册帐号 ...
- Unity中的资源管理
一.AssetBundle 相关 Q1:Unity中的SerializedFile是怎么产生的?请问用Unload(false)可以清除吗?因为读取了Bundle里面的内容后已经赋值给其他物体了.而且 ...
- Unity中使用Attribute
Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...
- Unity中2D和UGUI图集的理解与使用
图集 什么是图集? 在使用3D技术开发2D游戏或制作UI时(即使用GPU绘制),都会使用到图集,而使用CPU渲染的2D游戏和UI则不存在图集这个概念(比如Flash的原生显示列表),那么什么是图集呢? ...
随机推荐
- linux离线安装mysql5.7
下载安装包 下载地址:https://cdn.mysql.com//Downloads/MySQL-5.7/mysql-5.7.27-1.el7.x86_64.rpm-bundle.tar 上传到 / ...
- linux_ext4恢复超级块.txt
恢复ext4文件系统superblock 2014-04-01 17:00:17 分类: Linux 恢复ext4文件系统superblock1. Create ext4 文件系统.[root@loc ...
- Java8_stream的map和flatmap
假如我们有这样一个需求给定单词列表["Hello","World"],你想要返回列表["H","e","l&q ...
- 如何使用终端默认情况下阻止Mac应用保存到iCloud
当您保存要在Mac上的Pages,Numbers,TextEdit或其他基于云的应用程序中处理的文档时,该保存的默认位置是iCloud.尽管这对某些人或某些文档来说可能是一件好事,但您可能会厌倦每次更 ...
- python模拟进程状态
python模拟进程状态 我在参考资料中看到了两种实现方式,都做了尝试 代码1 from transitions import Machine class Matter: pass model = M ...
- 03-MySQL安装与配置
一.安装MySQL 1.我的是centos8,因此命令为: sudo yum install mysql-server 2.安装完成后查看是否启动 ps aux|grep mysql 3.启动mysq ...
- java大数习题
大数加法,题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1002 import java.math.BigInteger; import java.ut ...
- ETCD:与etcd进行交互
原文地址:Interacting with etcd 与etcd进行交互 用户更多的是通过putting或者是getting从etcd获取一个键对应的值.这一部分描述了如何通过etcdctl做这些工作 ...
- java spring是元编程框架---使用的机制是注解+配置
java spring是元编程框架---使用的机制是注解+配置
- Selenium(十九):unittest单元测试框架(五) Page Object设计模式
1. Page Object设计模式 Page Object是Selenium自动化测试项目开发实践的最佳设计模式之一,它主要体现在对界面交互细节的封装,这样可以使测试方案更关注于业务而非界面细节.从 ...