群体的操控行为

简介: 群体的操控行为

组行为

组行为的复杂性来源于个体间的交互,并遵守一些简单的规则。

模仿群体行为需要下面几种操控行为

  • 分离:避免个体在局部过于拥挤的操控力
  • 队列:朝向附近同伴的平均朝向的操控力
  • 聚集:向附近的同伴的平均位置移动的操控力

检测附近的AI角色

从上面的几种操控行为可以看出,每种操控行为都取决于附近的同伴。为了实现组行为,首先需要检测当前AI角色附近的其他AI角色,这要用一个雷达脚本来实现。

一般来说,角色的领域由一个距离和一个角度来定义。有时为了简化,用一个圆来定义。

1using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Radar : MonoBehaviour
{
    private Collider[] colliders;//碰撞体的组数
    private float timer = 0;//计时器
    public List<GameObject> neighbors;
    public float checkInterval = 0.3f;//设置检测的时间间隔
    public float detectRadius = 10f;//设置邻域半径
    public LayMask layersChecked;//设置检测哪一层的游戏对象
    void Start()
    {
        neighbors = new List<GameObject>();
    }
    void Update()
    {
        timer += Time.deltaTime;
        if(timer > checkInterval)
        {
            neighbors.Clear();
            colliders = Physics.OverlapSphere(transform.position, detectRadius, layersChecked);//查找当前AI角色邻域内的所有碰撞体
            for(int i = 0; i < colliders.Length; i++)//对于每个检测到的碰撞体,获取Vehicle组件,并且加入邻居列表钟
            {
                if (colliders[i].GetComponent<Vehicle>())
                    neighbors.Add(colliders[i].gameObject);
            }
            timer = 0;
        }
    }
}

分离

分离的目的是使角色与周围其他角色保持一定距离。实现时,为了计算分离行为所需的操控力,需要搜索指定领域内的其他邻居,然后对每个邻居计算与角色的距离向量,进行一系列处理得到操控力

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SteeringForSeparation : Steering
{
    public float comforDistance = 1;//可接受的距离
    public float multiplierInsideComfortDistance = 2;//当AI角色与邻居距离过近时的惩罚因子
 public override Vector3 Force()
    {
        Vector3 steeringForce = new Vector3(0, 0, 0);
        foreach(GameObject s in GetComponent<Radar>().neighbors)//遍历这个AI角色的邻居列表中的每个邻居
        {
            if ((s != null) && (s != this.gameObject))
            {
                Vector3 toNeighbor = transform.position - s.transform.position;//计算当前AI角色与邻居s之间的距离
                float length=toNeighbor.magnitude;
                steeringForce += toNeighbor.normalized / length;//计算这个邻居引起的操控力
                if (length < comforDistance)
                    steeringForce *= multiplierInsideComfortDistance;
            }
        }
        return steeringForce;
    }
}

队列

队列的目的是保持AI角色的运动朝向与邻居一致

通过迭代所有邻居,可以求出AI角色平均朝向向量以及速度平均向量,得到想要的朝向,然后减去AI当前朝向,就可以得到队列操控力

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SteeringForAlignment : Steering
{
    public override Vector3 Force()
    {
        Vector3 averageDirection = new Vector3(0, 0, 0);//当前AI角色的邻居平均朝向
        int neighborCount = 0;
        foreach(GameObject s in GetComponent<Radar>().neighbors)//遍历邻居
        {
            if ((s != null) && (s != this.gameObject))
            {
                averageDirection += s.transform.forward;
                neighborCount++;
            }
        }
        if(neighborCount > 0)
        {
            averageDirection/=(float)neighborCount;//求出平均朝向向量
            averageDirection -= transform.forward;//求出操控向量
        }
        return averageDirection;
    }
}

聚集

聚集的目的是使多个AI角色聚到一起。实现时,迭代所有邻居求出AI角色位置的平均值,然后利用靠近行为,将这个平均值作为目标位置。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SteeringForCohesion :Steering
{
    private Vector3 desiredVelocity;
    private Vehicle m_vehicle;
    private float maxSpeed;
    void Start()
    {
        m_vehicle = GetComponent<Vehicle>();
        maxSpeed = m_vehicle.maxSpeed;
    }
    public override Vector3 Force()
    {
        Vector3 steeringForce = new Vector3(0, 0, 0);//操控向量
        Vector3 centerOfMass = new Vector3(0, 0, 0);//AI角色的所有邻居的质心
        int neighborCount = 0;
        foreach (GameObject s in GetComponent<Radar>().neighbors)//遍历邻居
        {
            if ((s != null) && (s != this.gameObject))
            {
                centerOfMass += s.transform.position;
                neighborCount++;
            }
        }
        if (neighborCount > 0)
        {
            centerOfMass /= (float)neighborCount;//求出平均位置向量
            desiredVelocity = (centerOfMass - transform.position).normalized * maxSpeed;//与其速度为邻居平均位置与当前位置之差
            steeringForce = desiredVelocity - m_vehicle.velocity;
       }
        return steeringForce;
    }
}


相关文章
|
传感器 机器人 人机交互
眼睛会动,还能与人交谈、拥抱,iCub人形机器人这次具备远程操控
眼睛会动,还能与人交谈、拥抱,iCub人形机器人这次具备远程操控
111 0
|
传感器 存储 安全
智慧的车联网,是否会让我们失去操控的乐趣?
智慧的车联网,是否会让我们失去操控的乐趣?
182 0
智慧的车联网,是否会让我们失去操控的乐趣?
|
机器学习/深度学习
共享鸡皮疙瘩?庆应大学开发了一种贴身设备,利用腕带和颈带数据,分享刺激感受
共享鸡皮疙瘩?庆应大学开发了一种贴身设备,利用腕带和颈带数据,分享刺激感受
227 0
共享鸡皮疙瘩?庆应大学开发了一种贴身设备,利用腕带和颈带数据,分享刺激感受
|
自动驾驶
展望︱2017年 手机操控无人车
展望︱2017年 手机操控无人车
展望︱2017年 手机操控无人车
|
传感器 vr&ar 开发工具
现实中的VR产品离Immerex 的理想有多远?
现实中的VR产品离Immerex 的理想有多远?
140 0
现实中的VR产品离Immerex 的理想有多远?
日本航空公司打造新型VR设备,让用户身临其境地感受旅游目的地
该VR设备的关键组件是包含嗅觉装置的VR头显,不仅能够允许用户在视觉上享受,同时能够在嗅觉上感受当地的气息。
385 0
|
人工智能 物联网 语音技术
羊毛出在狗身上让猪来买单 - 智能音箱背后的平台经济
本文试图从平台经济学的角度来分析和解释为什么巨头们尤其是互联网巨头们纷纷杀入智能音箱的战场,又为什么开启疯狂的补贴大战,并预测一下之后的发展方向。 1. 智能音箱不是入口之争,而是平台之争。 2. 智能音箱行业的发展模式。 3. 智能音箱平台间的竞争。 4. 平台的生命周期和发展预测。
2345 0