可参考外文博客:点击打开链接
如图,实现时,为了计算分离行为所需要的操纵力,首先要搜索指定领域内的其他邻居,然后对每个邻居,计算AI角色到该邻居的向量r,将r归一化,得到排斥力的方向,然后排斥力的大小与距离成反比,然后把来自邻居的排斥力相加,就得到了分离行为的总操控力。
检测附近的邻居,雷达装置
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Radar : MonoBehaviour {
private Collider[] colliders;//碰撞体数组
private float timer = 0;//计时器
public List<GameObject> neighbors;//邻居列表
public float checkInterval = 0.3f;//检测邻居间隔
public float detectRadius = 2f;//检测半径
public LayerMask layersChecked;//检测哪一层的游戏对象
// Use this for initialization
void Start () {
neighbors = new List<GameObject>();
}
// Update is called once per frame
void Update () {
timer += Time.deltaTime;
if(timer>checkInterval)
{
neighbors.Clear();
colliders = Physics.OverlapSphere(transform.position, detectRadius, layersChecked);
for(int i = 0; i < colliders.Length; i++)
{
neighbors.Add(colliders[i].gameObject);
}
timer = 0;
}
}
}
排斥力的计算和实现场景
using UnityEngine;
using System.Collections;
public class SteeringForSeparation : MonoBehaviour
{
public Vector3 velocity = Vector3.zero;
public float mass = 50f;//质量
public float comfortDistance = 2;
public float multipierInsideComfortDistance = 1;
private Vector3 seperationForce;
private Vector3 CohesionForce;
private Vector3 AlignmentForce;
private Vector3 SumForce;
float length = 0;
// private Rigidbody rg;
// Use this for initialization
void Start () {
// rg = GetComponent<Rigidbody>();
}
// Update is called once per frame
void Update () {
Force();
CaluForce();
}
public void Force()
{
seperationForce = Vector3.zero;
AlignmentForce = Vector3.zero;
SumForce = Vector3.zero;
foreach (GameObject s in GetComponent<Radar>().neighbors)
{
if((s!=null)&s!=this.gameObject)
{
Vector3 toNeighbor = transform.position - s.transform.position; //与邻居的距离
length = toNeighbor.magnitude;
seperationForce += toNeighbor.normalized / length;
if(length<comfortDistance)
{
seperationForce *= multipierInsideComfortDistance;
}
}
}
SumForce += seperationForce;
}
public void CaluForce()
{
// Debug.Log(GetComponent<Radar>().neighbors.Count);
if ((GetComponent<Radar>().neighbors.Count>1))
{
Vector3 a = SumForce / mass; //牛二率
velocity += a*Time.deltaTime;
//Debug.Log (velocity);
//rg.AddForce(velocity, ForceMode.Force);
transform.Translate(velocity * Time.deltaTime, Space.World);
}
}
}
运行前:
运行后:
可以看到达到分离效果