Unity AI 感知侦探
2024-08-30 07:44:47
游戏中AI的感知用的最多的是看到或者听到,也就是:
1.视觉感知
2.听觉感知
视觉感知:
视觉感知一般会有一个视野范围,这个范围与角色的朝向有关,只有在视觉范围内角色才有可能感知得到,这个范围与一个扇形接近,可以直接用半径和角度来控制。
潜在目标除了需要在视视觉范围内之外,探索者的视线还不能被其他障碍物遮挡,这里可以用射线来检测——发出一条从探索者到潜在目标的射线,如果目标是这条射线撞到的第一个单位,则该单位可以被看到,否则被忽略。
using System.Collections.Generic;
using UnityEngine; public class AIViewPerception : MonoBehaviour
{
//视野半径
public float radius=10f;
//视野的角度范围
public float angel=120f; //侦察的结果
public List<GameObject> PerceptionResult { get; private set; } /// <summary>
/// 进行一次侦察
/// </summary>
/// <param name="explorer">探索者</param>
/// <param name="targets">潜在目标集</param>
public void Check(GameObject explorer,List<GameObject> targets)
{
PerceptionResult.Clear(); foreach(var item in targets)
{
//距离判断,这里用平方减少系统开根号的计算量
Vector3 offset = item.transform.position - explorer.transform.position;
if (offset.sqrMagnitude > radius*radius)
continue; //角度判断,是否在视线范围内
float angel = Vector3.Angle(explorer.transform.forward, offset.normalized);
if (angel > this.angel * 1.0f / )
continue; //射线判断,是否被其它目标或障碍物阻挡
Ray ray = new Ray(explorer.transform.position, offset);
RaycastHit info;
if (Physics.Raycast(ray,out info,radius))
{
if (info.collider.gameObject == item)
{
PerceptionResult.Add(item);
}
}
}
} void Start()
{
//测试
PerceptionResult = new List<GameObject>();
var targets =new List<GameObject>(GameObject.FindGameObjectsWithTag("Target"));
Check(gameObject, targets);
foreach(var result in PerceptionResult)
{
Debug.Log(result.name);
}
}
听觉感知:
听觉感知不像视觉感知那样跟朝向有关,也没有一个角度范围,但听觉感知一般与声源的距离有关;距离越远声音越小,在距离相对较远的地方由于接收到的音量逐渐变小,更好的处理方式是根据距离的远近有感知丢失的可能性。
这里采用两个听力半径作为区分,一个是安全听力半径,一个是最大听力半径,在安全听力半径内一定能感知到声源,但超过安全半径后,直到最大听力范围,感知到声源的概率呈现线性降低,直到最大听力范围处为0。
using System.Collections.Generic;
using UnityEngine; public class AIListenPerception : MonoBehaviour
{
//最大听力半径
public float maxRadius = 10f;
//安全听力半径
public float safeRadius = 5f; //侦听结果
public Dictionary<AudioSource,float> PerceptionResult { get; private set; } /// <summary>
/// 进行一次侦听
/// </summary>
/// <param name="explorer">探索者</param>
/// <param name="targets">声源目标集</param>
public void Check(GameObject explorer, List<AudioSource> targets)
{
PerceptionResult.Clear(); foreach(var item in targets)
{
//最大听力范围判断
Vector3 offset = item.transform.position - explorer.transform.position;
if (offset.sqrMagnitude > maxRadius * maxRadius)
continue; //侦听丢失的概率判断:计算出一个声源距离比例权重,距离越远,权重越大,侦听丢失的概率越大
float distance = offset.magnitude;
float weight = (distance - safeRadius) * 1.0f / (maxRadius - safeRadius);
if (Random.value < weight)
continue; //计算真实的侦听到音量,与距离成反比
float volume = item.volume *(- distance / maxRadius);
PerceptionResult.Add(item, volume);
}
} private void Start()
{
//测试
PerceptionResult = new Dictionary<AudioSource, float>();
var targets = new List<GameObject>(GameObject.FindGameObjectsWithTag("Target"));
List<AudioSource> audioSources = new List<AudioSource>();
foreach(var item in targets)
{
audioSources.Add(item.GetComponent<AudioSource>());
}
Check(gameObject, audioSources);
foreach (var result in PerceptionResult)
{
Debug.Log("audioSource : " + result.Key.gameObject.name);
Debug.Log("volume : "+ result.Value);
}
}
最新文章
- dynamic 的使用 待续
- Java NIO入门
- codevs2495 水叮当的舞步 IDA*
- Java基础——I/O续
- Twitter:蓄水池储水量问题
- CopyU!新插件 CopyPC2U正式发布!
- 团队作业8——第二次项目冲刺(Beta版本)5.24
- 基于 xorm 的服务端框架 XGoServer
- scala开发环境安装
- [Err] 1418 - This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its declaration and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creator【s
- caffe:fine-tuning
- mysql-utilities1.6
- 第一章 CSS基础
- 站在巨人肩上的.NET Core 2.1
- WebForm的初步认识
- CentOS 安装Parallels Tools
- c++拷贝构造函数,深拷贝,浅拷贝,对象内存
- 15.并发容器之ConcurrentLinkedQueue
- python 日志模块工具类
- Epplus导出Excel(DataTable)
热门文章
- zhy2_rehat6_mysql02 - 5.7主从搭建.txt
- Filter拦截器和Listen监听器
- pycharm中将文件目录标记为sources root和sys.path.append()效果一样
- [Go] golang中的包管理
- ResultSet RS_resultxtgg=connDbBean.executeQuery(sqlxtgg);
- Java之Map接口(双列集合)
- UDP组播
- typescript与nodejs(一)最简单的webserver
- 国产处理器的逆袭机会——RISC-V
- InfluxDB从原理到实战 - 一篇文章搞懂InfluxDB时区