如果不想用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随机巡逻障碍物预判与快速运动时物理穿透的思考的更多相关文章

  1. 解决Unity中模型部件的MeshCollider不随动画一起运动的问题

    Unity的3d游戏开发中,经常遇到需要将模型的某一部分(比如武器),单独做碰撞处理的情况. 导入模型后,给武器部分添加MeshCollider,MeshCollider的Mesh通常包含在模型里,如 ...

  2. Unity中各个平台的预编译的运用方式

    1,unity中官方文档的一个操纵关键词   Platform Dependent Compilation 2,常用的预编译关键词    UNITY_EDITOR    编辑器调用.UNITY_STA ...

  3. Unity中List的随机排序(乱序)

    为什么要给List排序做一个Unity限定条件呢 首先,是C#中的List泛型,若是Java,直接调用Collection.shuffle()就OK了 而Unity的C#版本较低,不能使用Random ...

  4. Unity中的协程(一)

    这篇文章很不错的问题,推荐阅读英文原版: Introduction to Coroutines Scripting with Coroutines   这篇文章转自:http://blog.csdn. ...

  5. Unity Rain Ai 插件基本使用(二)

    前言 在前面的教程中我们已经基本实现了路径导航和障碍物规避. 但是这样我们并没有让我们的角色学会思考,他只是机械的去完成一些步骤,这并不能体现Rain插件的智能. 一个角色他应该有多个不同的状态,待机 ...

  6. 在Unity中创建攻击Slot系统

    http://www.manew.com/thread-109310-1-1.html 马上注册,结交更多好友,享用更多功能,让你轻松玩转社区. 您需要 登录 才可以下载或查看,没有帐号?注册帐号  ...

  7. Unity中的资源管理

    一.AssetBundle 相关 Q1:Unity中的SerializedFile是怎么产生的?请问用Unload(false)可以清除吗?因为读取了Bundle里面的内容后已经赋值给其他物体了.而且 ...

  8. Unity中使用Attribute

    Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...

  9. Unity中2D和UGUI图集的理解与使用

    图集 什么是图集? 在使用3D技术开发2D游戏或制作UI时(即使用GPU绘制),都会使用到图集,而使用CPU渲染的2D游戏和UI则不存在图集这个概念(比如Flash的原生显示列表),那么什么是图集呢? ...

随机推荐

  1. mysql操作进阶

    # ### part1 单表查询# sql 查询语句的完整语法 ''' select .. from .. where .. group by .. having .. order by .. lim ...

  2. Centos7 基于SVN+Apache+IF.svnadmin实现web管理

    1.简单介绍: iF.SVNAdmin应用程序是您的Subversion授权文件的基于Web的GUI.它基于PHP 5.3,需要安装一个Web服务器(Apache).该应用程序不需要数据库后端或任何类 ...

  3. [Go] golang定时器与redis结合

    golang定时器与redis结合,每隔1秒ping一下,每隔20秒llen一下队列的长度 package main import ( "fmt" "time" ...

  4. 在 Cocos2d-x 中添加自己的微博链接

    配置:OS X 10.10 + Xcode 6.0 + Cocos2d-x-3.2 一.Android 端代码 1.在 Cocos2dxActivity.java 中添加openUrl函数并导入响应包 ...

  5. Django中获取参数(路径,查询,请求头,请求体)

    一.通常HTTP协议向服务器传参有几种途径 : 提取URL的特定部分,如/weather/shanghai/2018,可以在服务器端的路由中用正则表达式截取: 查询字符串(query string), ...

  6. 字典树(Trie)详解

    详解字典树(Trie) 本篇随笔简单讲解一下信息学奥林匹克竞赛中的较为常用的数据结构--字典树.字典树也叫Trie树.前缀树.顾名思义,它是一种针对字符串进行维护的数据结构.并且,它的用途超级广泛.建 ...

  7. [译]OpenSSL Cookbook

    记录个人学习过程吧,顺便翻译一下.另外,本文并不会包括原连接中的所有内容,仅包括个人在工作中会经常遇到的. 参考:OpenSSL Cookbook 前言 由于协议特性和实现的复杂性,有时很难确定安全服 ...

  8. 自学Java,需要掌握什么内容才能找到满意的工作?

    首先,这个问题主要问:自学Java编程技术,如果才能找到一份Java编程的工作.按照现在的招聘标准来看,无论你去哪个公司面试,你只需要满足他们公司的需求就可以. 找到一份Java编程工作需要掌握的内容 ...

  9. redis的embstr编码

    问题来了 今天在看书籍<Redis设计与实现>的时候,在8.2字符串对象里面写到 如果字符串对象保存的是一个字符串值, 并且这个字符串值的长度大于 39 字节, 那么字符串对象将使用一个简 ...

  10. 多线程七 AQS

    一 . 简介AQS AQS简介 在同步组件的实现中,AQS是核心部分,同步组件的实现者,通过使用AQS提供的模板方法 实现同步组件语义 AQS实现了对同步状态的管理以及阻塞线程进行排队,等待通知等等一 ...