zoukankan      html  css  js  c++  java
  • 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     }
  • 相关阅读:
    求随机数平均值方法 求随机数方差方法 求正态分布的随机数
    combox 绑定
    winform界面textbox框 鼠标经过时出现浮动
    Regex
    C# 3.0 一行求方差
    通过Linq 实现DataTable Group By
    ORACLE 时间运算
    发布几个国外的XHTML模板站,DIV+CSS模板下载
    C# 3.0新特性系列:隐含类型var
    在NTier 或多层应用程序中使用ADO.NET Entity Framework
  • 原文地址:https://www.cnblogs.com/koshio0219/p/11600238.html
Copyright © 2011-2022 走看看