专栏首页U3DUnity AI 感知侦探

Unity AI 感知侦探

游戏中AI的感知用的最多的是看到或者听到,也就是:

1.视觉感知

2.听觉感知

视觉感知:

视觉感知一般会有一个视野范围,这个范围与角色的朝向有关,只有在视觉范围内角色才有可能感知得到,这个范围与一个扇形接近,可以直接用半径和角度来控制。

潜在目标除了需要在视视觉范围内之外,探索者的视线还不能被其他障碍物遮挡,这里可以用射线来检测——发出一条从探索者到潜在目标的射线,如果目标是这条射线撞到的第一个单位,则该单位可以被看到,否则被忽略。

 1 using System.Collections.Generic;
 2 using UnityEngine;
 3 
 4 public class AIViewPerception : MonoBehaviour
 5 {
 6     //视野半径
 7     public  float radius=10f;
 8     //视野的角度范围
 9     public  float angel=120f;
10 
11     //侦察的结果
12     public  List<GameObject> PerceptionResult { get; private set; }
13 
14     /// <summary>
15     /// 进行一次侦察
16     /// </summary>
17     /// <param name="explorer">探索者</param>
18     /// <param name="targets">潜在目标集</param>
19     public void Check(GameObject explorer,List<GameObject> targets)
20     {
21         PerceptionResult.Clear();
22 
23         foreach(var item in targets)
24         {
25             //距离判断,这里用平方减少系统开根号的计算量
26             Vector3 offset = item.transform.position - explorer.transform.position;
27             if (offset.sqrMagnitude > radius*radius)
28                 continue;
29 
30             //角度判断,是否在视线范围内
31             float angel = Vector3.Angle(explorer.transform.forward, offset.normalized);
32             if (angel > this.angel * 1.0f / 2)
33                 continue;
34 
35             //射线判断,是否被其它目标或障碍物阻挡
36             Ray ray = new Ray(explorer.transform.position, offset);
37             RaycastHit info;
38             if (Physics.Raycast(ray,out info,radius))
39             {
40                 if (info.collider.gameObject == item)
41                 {
42                     PerceptionResult.Add(item);
43                 }
44             }
45         }
46     }
47 
48     void Start()
49     {
50         //测试
51         PerceptionResult = new List<GameObject>();
52         var targets =new List<GameObject>(GameObject.FindGameObjectsWithTag("Target"));
53         Check(gameObject, targets);
54         foreach(var result in PerceptionResult)
55         {
56             Debug.Log(result.name);
57         }
58     }

听觉感知:

听觉感知不像视觉感知那样跟朝向有关,也没有一个角度范围,但听觉感知一般与声源的距离有关;距离越远声音越小,在距离相对较远的地方由于接收到的音量逐渐变小,更好的处理方式是根据距离的远近有感知丢失的可能性。

这里采用两个听力半径作为区分,一个是安全听力半径,一个是最大听力半径,在安全听力半径内一定能感知到声源,但超过安全半径后,直到最大听力范围,感知到声源的概率呈现线性降低,直到最大听力范围处为0。

 1 using System.Collections.Generic;
 2 using UnityEngine;
 3 
 4 public class AIListenPerception : MonoBehaviour
 5 {
 6     //最大听力半径
 7     public float maxRadius = 10f;
 8     //安全听力半径
 9     public float safeRadius = 5f;
10 
11     //侦听结果
12     public Dictionary<AudioSource,float> PerceptionResult { get; private set; }
13 
14     /// <summary>
15     /// 进行一次侦听
16     /// </summary>
17     /// <param name="explorer">探索者</param>
18     /// <param name="targets">声源目标集</param>
19     public void Check(GameObject explorer, List<AudioSource> targets)
20     {
21         PerceptionResult.Clear();
22 
23         foreach(var item in targets)
24         {
25             //最大听力范围判断
26             Vector3 offset = item.transform.position - explorer.transform.position;
27             if (offset.sqrMagnitude > maxRadius * maxRadius)
28                 continue;
29 
30             //侦听丢失的概率判断:计算出一个声源距离比例权重,距离越远,权重越大,侦听丢失的概率越大
31             float distance = offset.magnitude;
32             float weight = (distance - safeRadius) * 1.0f / (maxRadius - safeRadius);
33             if (Random.value < weight)
34                 continue;
35 
36             //计算真实的侦听到音量,与距离成反比
37             float volume = item.volume *(1- distance / maxRadius);
38             PerceptionResult.Add(item, volume);
39         }
40     }
41 
42     private void Start()
43     {
44         //测试
45         PerceptionResult = new Dictionary<AudioSource, float>();
46         var targets = new List<GameObject>(GameObject.FindGameObjectsWithTag("Target"));
47         List<AudioSource> audioSources = new List<AudioSource>();
48         foreach(var item in targets)
49         {
50             audioSources.Add(item.GetComponent<AudioSource>());
51         }
52         Check(gameObject, audioSources);
53         foreach (var result in PerceptionResult)
54         {
55             Debug.Log("audioSource : " + result.Key.gameObject.name);
56             Debug.Log("volume : "+ result.Value);
57         }
58     }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Unity 子弹生成系统

    子弹系统和粒子系统比较类似,为了创建出五花八门的子弹,例如追踪,连续继承,散弹等,需要一个拥有众多参数的子弹生成器,这里叫它Shooter好了。

    汐夜koshio
  • Unity BehaviorDesigner行为树基础总结

    当Player有Input时按照Input值来移动,无Input时查找最近的可攻击目标,如果能找到就执行攻击;当既没有Input也没有找到攻击目标时,那就一直处...

    汐夜koshio
  • Unity LineRenderer 射线检测 激光攻击

    在进行激光攻击的脚本编写前,我们先进行一定程度的想象,思考激光和普通的远程攻击有哪些不太一样的地方。

    汐夜koshio
  • 点论 | 一文读懂ILM

    ILM = interface logic model, 是用来描述设计『接口逻辑』的一种『模型』,一个完整的ILM 包括:netlist, DEF, SPEF...

    老秃胖驴
  • SocketIo+SpringMvc实现文件的上传下载

    socketIo不仅可以用来做聊天工具,也可以实现局域网(当然你如果有外网也可用外网)内实现文件的上传和下载,下面是代码的效果演示:

    Dream城堡
  • 数据结构与算法-打印心形算法

    cwl_java
  • Java Servlet 做一个简单的分IP访问统计系统

    本文由 Alone88 创作,采用 知识共享署名4.0 国际许可协议进行许可 本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名 最后编辑时间为:...

    Alone88
  • Lombok @Builder注解与继承

    Builder 模式的链式调用写起来很方便,但是自己实现 Builder 模式要在 POJO 类中写较多代码。Lombok 的 @Builder注解可以方便的支...

    撸码那些事
  • .NET应用架构设计—重新认识分层架构(现代企业级应用分层架构核心设计要素)

    阅读目录: 1.背景介绍 2.简要回顾下传统三层架构 3.企业级应用分层架构(现代分层架构的基本演变过程) 3.1.服务层中应用契约式设计来解决动态条件不...

    王清培
  • Jenkins Pipeline高级用法-ShareLibrary

    https://github.com/zeyangli/ShareLibrary-jenkins.git

    泽阳

扫码关注云+社区

领取腾讯云代金券