可参考外文博客:点击打开链接
如图,实现时,为了计算分离行为所需要的操纵力,首先要搜索指定领域内的其他邻居,然后对每个邻居,计算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); } } }
运行前:
运行后:
可以看到达到分离效果