AI角色对环境信息的感知
作者:追风剑情 发布于:2015-6-7 13:00 分类:Unity3d
在游戏中,AI角色可以通过两种方式获得游戏世界的信息——轮询和事件驱动。
1、严格来说,感知系统并不算是游戏AI的一部分,但是,它的实现质量直接关系到AI系统的好坏,因此,对感知系统拥有良好的理解,将会非常有利于构建更强大的AI系统。
2、在游戏中,感知的开销可能会很大,因此,许多情况下,感知不能也不需要在每帧中进行。
3、视线查询(Line-of-Sight),在Unity3D中,Raycast调用可以实现视线查询,遗憾的是速度相对较慢,当场景中有大量物体时进行调用,或调用过于频繁时,开销很大。
触发器
触发器这个概念是与事件驱动系统相对应的,触发器是AI角色能对其做出反应的任何“刺激源”,是它们触发了AI角色感兴趣的事件。例如,听觉或视觉刺激,例如枪声、爆炸、临近的敌人或尸体,也可能由游戏中的非AI角色产生。许多触发器具有这样的特性,即当游戏实体进入触发器所在的范围内时,这个触发器就会被触发。触发器范围一般是以触发器为中心的一个区域,在二维游戏中通常是圆形或矩形,在三维游戏中通常是球体、立方体或圆柱体的。
在游戏设计中,触发器是非常常见的,可以用它们创建各种事件和行为。
- 当玩家射击时,一个声音触发器就被添加到场景中,这样,周围的AI角色会注意到枪声,决定是否逃避或赶来参与战斗。
- 当玩家打倒一个护卫,护卫倒在地下时,相应的视觉触发器使得其他靠近的AI角色对尸体做出反应,决定避开这个区域或上前查看等。
- 门的手柄可以是一个接触触发器,当玩家触碰到它时,门就会打开。
- AI角色沿着昏暗的走廊走向某个地方,地面是对压力敏感的,这样随着AI角色的走动,触发器发出脚步声的回响。
- 在雪地上行走的角色会留下脚印,当角色被击中而逃走时可能会留下血迹,这些都可以是视觉触发器,AI角色可以沿着脚印或血迹追逐角色。
如果只考虑模拟人的感觉,那么上面提到过的触发器似乎已经够了,味觉和嗅在游戏中很少使用,而且也可以模拟听觉感知的方式实现。但是游戏中还有一些其他种类的触发器。例如:
- 时间相关的触发器。游戏角色可能会需要在6点回家吃饭,或者晚上7点后怪物出现的几率增大,又或者游戏进行一定时间后,发生某种剧情。另外,还有每隔一段时间就需要执行的触发,比如刷新怪物等。
- 来自输入接口的触发器。例如,玩家按下Esc键,会触发过场动画等。
- 当玩家开采资源或建造单位到达一个值后触发,发生某些事情。
- 某一个单位发生事件后触发,比如,死亡、被攻击、升级、释放一项技能、购买物品等。
- 单位进入或离开特定区域时触发。例如,进入水域时,要播放游泳的动画,发生高度突变时,播放攀爬动画等,或者进入突袭区时,做出某种反应等。
- 指定单位的生命值在某个值以上或以下时触发,可以用于设定剧情。
由于每个AI角色的特点和能力不同,AI角色可以自己决定对哪些触发器做出反应,而忽略另一些触发器,例如,可能有些AI角色是聋的,无法对声音做出反应,或者听觉能力较弱,只能对很近的声音做出反应等。
常用感知类型的实现
游戏中最常用的感知类型是视觉和听觉。对于视觉,需要配对的视觉触发器和视觉感知器;为了实现听觉,需要配对的声音触发器和声音感知器。总的来说,游戏中有多个触发器以及多个感知器,可以通过一个管理中心——事件管理器,统一对它们进行管理。
另外,游戏中还常常需要模拟人的记忆。例如,如果玩家为了躲避AI角色射击,向右跨一步,躲到墙的后面,如果这时AI角色马上就忘了玩家,重新进入巡逻状态,那就太不真实了。为此,感知系统还要包括一个记忆感知器。
触觉感知
触觉感知可以交给Unity3D的物理引擎来处理。通过为一个游戏物体加上碰撞体,并选中Inspector面板中的isTrigger属性,就可以把它标记为“触发器”。触发器不受物理引擎的控制,当触发器和另一个Collider发生碰撞时(其中至少有一个附加了Rigidbody组件),会发出3个触发信息,分别是OnTriggerEnter(当碰撞体Collider进入trigger触发器时调用),OnTriggerExit(当碰撞体Collider停止触发trigger时调用),OnTriggerStay(当碰撞体Collider接触trigger触发器时,这个函数将在每帧被调用)。在这3个函数中编写相应的代码,就可以实现触觉感知了。
因此,Unity3D已经为触觉感知提供了事件管理器,所以在事件感知器中,不再需要编写触觉相关的代码。
灵活应用触觉感知可以实现许多事件,比如显示信息、自动门的开启、生命值供给器、武器供给器等。
==========================感知系统框架代码=============================
using UnityEngine; using System.Collections; using System.Collections.Generic; /// <summary> /// 这个类负责管理触发器的集合。它维护一个当前所有触发器的列表,当每个触发器被创建时, /// 都会向这个管理器注册自身,加入到这个列表中,事件管理器负责更新和处理所有的触发器, /// 并且当触发器已过期需要被移除时,从列表中删除它们。 /// 事件管理器还维护了一个感知器列表,每个感知器被创建时,向这个管理器注册,加入到感知器列表中。 /// </summary> public class TriggerSystemManager : MonoBehaviour { //初始化当前感知器列表 List<Sensor> currentSensors = new List<Sensor>(); //初始化当前触发器列表 List<Trigger> currentTriggers = new List<Trigger>(); //记录当前时刻需要被移除的感知器,例如感知体死亡,需要移除感知器时; List<Sensor> sensorsToRemove; //记录当前时刻需要被移除的触发器,例如触发器已过期时; List<Trigger> triggersToRemove; void Start () { sensorsToRemove = new List<Sensor> (); triggersToRemove = new List<Trigger> (); } private void UpdateTriggers() { foreach (Trigger t in currentTriggers) { if(t.toBeRemoved){ triggersToRemove.Add(t); }else{ t.Updateme(); } } foreach (Trigger t in triggersToRemove) currentTriggers.Remove (t); } private void TryTriggers() { foreach (Sensor s in currentSensors) { //如果s所对应的感知体还存在(没有因死亡而被销毁) if(s.gameObject != null){ foreach (Trigger t in currentTriggers){ t.Try(s); } }else{ sensorsToRemove.Add(s); } } foreach (Sensor s in sensorsToRemove) currentSensors.Remove (s); } void Update () { //更新所有触发器内部状态 UpdateTriggers (); //迭代所有感知器和触发器,做出相应的行为 TryTriggers (); } //用于注册触发器 public void RegisterTrigger(Trigger t) { currentTriggers.Add (t); } //用于注册感知器 public void RegisterSensor(Sensor s) { currentSensors.Add (s); } }
using UnityEngine; using System.Collections; /// <summary> /// 这个类是所有触发器的基类,视觉触发器和听觉触发器都是它的派生类。 /// </summary> public class Trigger : MonoBehaviour { //保存管理中心对象 protected TriggerSystemManager manager; //触发器的位置 protected Vector3 position; //触发器的半径 public int radius; //当前触发器是否需要被移除 public bool toBeRemoved; //这个方法检查作为参数的感知器s是否在触发器的作用范围内 //(或当前触发器是否能真正被感知器sensor感觉到),如果是,那么采取相应的行为。 //这个方法需要在派生类中实现。 public virtual void Try( Sensor sensor ) { } //这个方法更新触发器的内部状态,例如,声音触发器的剩余有效时间等。 public virtual void Updateme() { } //这个方法检查感知器sensor是否在触发器的作用范围内 //或当前触发器是否能真正被感知器s感觉到,如果是,返回true,如果不是,返回false //它被Try()调用;需要在派生类中实现。 protected virtual bool isTouchingTrigger( Sensor sensor) { return false; } void Awake () { //查找管理器并保存 manager = FindObjectOfType<TriggerSystemManager> (); } protected void Start () { //这时不需要移除,置为false toBeRemoved = false; } void Update () { } }
using UnityEngine; using System.Collections; /// <summary> /// Sensor类是所有感知器的基类,视觉感知器和听觉感知器都是它的派生类。 /// 这个类中包含了对感知器类型的枚举定义和变量,还保存了事件管理器。 /// </summary> public class Sensor : MonoBehaviour { protected TriggerSystemManager manager; public enum SensorType { sight, sound, health } public SensorType sensorType; void Awake () { //查找管理器并保存 manager = FindObjectOfType<TriggerSystemManager> (); } void Start () { } void Update () { } public virtual void Notify (Trigger t) { } }
========================== End ====================================
标签: Unity3d
日历
最新文章
随机文章
热门文章
分类
存档
- 2024年11月(3)
- 2024年10月(5)
- 2024年9月(3)
- 2024年8月(3)
- 2024年7月(11)
- 2024年6月(3)
- 2024年5月(9)
- 2024年4月(10)
- 2024年3月(11)
- 2024年2月(24)
- 2024年1月(12)
- 2023年12月(3)
- 2023年11月(9)
- 2023年10月(7)
- 2023年9月(2)
- 2023年8月(7)
- 2023年7月(9)
- 2023年6月(6)
- 2023年5月(7)
- 2023年4月(11)
- 2023年3月(6)
- 2023年2月(11)
- 2023年1月(8)
- 2022年12月(2)
- 2022年11月(4)
- 2022年10月(10)
- 2022年9月(2)
- 2022年8月(13)
- 2022年7月(7)
- 2022年6月(11)
- 2022年5月(18)
- 2022年4月(29)
- 2022年3月(5)
- 2022年2月(6)
- 2022年1月(8)
- 2021年12月(5)
- 2021年11月(3)
- 2021年10月(4)
- 2021年9月(9)
- 2021年8月(14)
- 2021年7月(8)
- 2021年6月(5)
- 2021年5月(2)
- 2021年4月(3)
- 2021年3月(7)
- 2021年2月(2)
- 2021年1月(8)
- 2020年12月(7)
- 2020年11月(2)
- 2020年10月(6)
- 2020年9月(9)
- 2020年8月(10)
- 2020年7月(9)
- 2020年6月(18)
- 2020年5月(4)
- 2020年4月(25)
- 2020年3月(38)
- 2020年1月(21)
- 2019年12月(13)
- 2019年11月(29)
- 2019年10月(44)
- 2019年9月(17)
- 2019年8月(18)
- 2019年7月(25)
- 2019年6月(25)
- 2019年5月(17)
- 2019年4月(10)
- 2019年3月(36)
- 2019年2月(35)
- 2019年1月(28)
- 2018年12月(30)
- 2018年11月(22)
- 2018年10月(4)
- 2018年9月(7)
- 2018年8月(13)
- 2018年7月(13)
- 2018年6月(6)
- 2018年5月(5)
- 2018年4月(13)
- 2018年3月(5)
- 2018年2月(3)
- 2018年1月(8)
- 2017年12月(35)
- 2017年11月(17)
- 2017年10月(16)
- 2017年9月(17)
- 2017年8月(20)
- 2017年7月(34)
- 2017年6月(17)
- 2017年5月(15)
- 2017年4月(32)
- 2017年3月(8)
- 2017年2月(2)
- 2017年1月(5)
- 2016年12月(14)
- 2016年11月(26)
- 2016年10月(12)
- 2016年9月(25)
- 2016年8月(32)
- 2016年7月(14)
- 2016年6月(21)
- 2016年5月(17)
- 2016年4月(13)
- 2016年3月(8)
- 2016年2月(8)
- 2016年1月(18)
- 2015年12月(13)
- 2015年11月(15)
- 2015年10月(12)
- 2015年9月(18)
- 2015年8月(21)
- 2015年7月(35)
- 2015年6月(13)
- 2015年5月(9)
- 2015年4月(4)
- 2015年3月(5)
- 2015年2月(4)
- 2015年1月(13)
- 2014年12月(7)
- 2014年11月(5)
- 2014年10月(4)
- 2014年9月(8)
- 2014年8月(16)
- 2014年7月(26)
- 2014年6月(22)
- 2014年5月(28)
- 2014年4月(15)
友情链接
- Unity官网
- Unity圣典
- Unity在线手册
- Unity中文手册(圣典)
- Unity官方中文论坛
- Unity游戏蛮牛用户文档
- Unity下载存档
- Unity引擎源码下载
- Unity服务
- Unity Ads
- wiki.unity3d
- Visual Studio Code官网
- SenseAR开发文档
- MSDN
- C# 参考
- C# 编程指南
- .NET Framework类库
- .NET 文档
- .NET 开发
- WPF官方文档
- uLua
- xLua
- SharpZipLib
- Protobuf-net
- Protobuf.js
- OpenSSL
- OPEN CASCADE
- JSON
- MessagePack
- C在线工具
- 游戏蛮牛
- GreenVPN
- 聚合数据
- 热云
- 融云
- 腾讯云
- 腾讯开放平台
- 腾讯游戏服务
- 腾讯游戏开发者平台
- 腾讯课堂
- 微信开放平台
- 腾讯实时音视频
- 腾讯即时通信IM
- 微信公众平台技术文档
- 白鹭引擎官网
- 白鹭引擎开放平台
- 白鹭引擎开发文档
- FairyGUI编辑器
- PureMVC-TypeScript
- 讯飞开放平台
- 亲加通讯云
- Cygwin
- Mono开发者联盟
- Scut游戏服务器引擎
- KBEngine游戏服务器引擎
- Photon游戏服务器引擎
- 码云
- SharpSvn
- 腾讯bugly
- 4399原创平台
- 开源中国
- Firebase
- Firebase-Admob-Unity
- google-services-unity
- Firebase SDK for Unity
- Google-Firebase-SDK
- AppsFlyer SDK
- android-repository
- CQASO
- Facebook开发者平台
- gradle下载
- GradleBuildTool下载
- Android Developers
- Google中国开发者
- AndroidDevTools
- Android社区
- Android开发工具
- Google Play Games Services
- Google商店
- Google APIs for Android
- 金钱豹VPN
- TouchSense SDK
- MakeHuman
- Online RSA Key Converter
- Windows UWP应用
- Visual Studio For Unity
- Open CASCADE Technology
- 慕课网
- 阿里云服务器ECS
- 在线免费文字转语音系统
- AI Studio
- 网云穿
- 百度网盘开放平台
- 迅捷画图
- 菜鸟工具
- [CSDN] 程序员研修院
- 华为人脸识别
- 百度AR导航导览SDK
- 海康威视官网
- 海康开放平台
- 海康SDK下载
- git download
交流QQ群
-
Flash游戏设计: 86184192
Unity游戏设计: 171855449
游戏设计订阅号