鱼群AI群聚算法

2018-01-18  本文已影响0人  hh5460

通过模拟鱼群或是雁群的群聚AI算法主要的有三种行为分别是分散,对齐,凝聚
即当鱼群之间距离靠的过近时它们会主动散开,当距离过远时它们又会往一起凝聚,其实散开和凝聚更多的都是左右两侧的力,但是如果还要整齐的向前行动,还需要一个对齐的力,这个力一般是指向行进方向上的,即周围个体的平均速度方向

下面基于Unity,提供一个概括实现思路

分散:每个单位行动时,要避免撞上其临近单位。

//1.首先要获得周围的鱼个体
//通过如下方法获得检测半径内的鱼,也就是附近的鱼(注意去除掉自己)
Collider[] colliders = Physics.OverlapSphere(transfrom.position,检测半径)
//得到得到去除自己后的ecm_colliders

#2计算出分离的力
#通过遍历附近的鱼与当前位置的方向计算出相互间排斥力的大小(每隔一段时间调用)
foreach(var c in ecm_colliders)
{
    Vector3 dir = transform.position - c.transform.position;
    //由于相互之间是排斥力,所以向量长度dir.magnitude越长,该方向上的力越小,反之亦然
    //注意:repulsionForceALL 是外部定义的,计算附近鱼群给当前目标的合力
    repulsionForceALL += dir.normalized / dir.magnitude;
}
//repulsionForceALL仅仅计算的是分离的力,总的力的大小,包括分离聚集和对齐的力为allForce
allForce += repulsionForceALL;
//得到附近给的力的合力之后,则可以在FixedUpdate中求出加速度
void FixedUpdate()
{
    //根据牛二定律计算出加速度 和 当前速度包含方向
    velocity += (allForce / m) * Time.fixedDeltaTime;
    //将鱼的朝向转向速度的方向
    transfrom.rotation = Quaternion.Slerp(transfrom.rotation,transform.LookAt(velocity),Time.fixedDeltaTime);
}

对齐:每个单位行动时,都要把自己对齐在其临近单位的平均方向上。

//大致同上,这里仅仅讲诉如何获取对齐的力
//这里ecm_colliders2不等于上面的ecm_colliders不同,因为它们的检测半径范围不一样
foreach(var c in ecm_colliders2)
{
    //对齐的力实际上就应该等于附近每个鱼当前的方向,取所有方向总的朝向
    allDir += c.transform.forward;
}
//将目标方向减去当前方向,得到使当前个体向周围方向对齐的力
allForce += allDir.normalized - transform.forward;       //后面在fixedUpdate中同理调用

凝聚:每个单位都往其临近单位的平均位置行动。

N个点的中心坐标(x,y) = ( (x1+x2+x3+...+xN)/N , (y1+y2+y3+...+yN)/N )

//大致同上,这里仅仅讲诉如何获取聚集的力
//这里ecm_colliders等同于上面分散的ecm_colliders
foreach(var c in ecm_colliders)
{
    //聚集的力实际上就应该是先计算周围所有点的中心,然后将当前物体向中心靠近
    centerPosition += c.transform.position;
}
//得到中心的位置
centerPosition /= ecm_colliders.Length; 
//中心位置减去当前的位置,得到朝向中心位置的方向,直接将其当作聚集的作用力
allForce +=  centerPosition  - tranform.position; 

PS:由于最后所有的分散,对齐,聚集的力的大小都没有做权值处理,所有可能模拟的不够真实,可以分别将其乘以对应的分量控制其权值大小,来做到更真实的模拟

分散,对齐,聚集.png
上一篇 下一篇

猜你喜欢

热点阅读