群体行为之分离

可参考外文博客:点击打开链接


如图,实现时,为了计算分离行为所需要的操纵力,首先要搜索指定领域内的其他邻居,然后对每个邻居,计算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);
        }
   
    }
}

运行前:


运行后:


可以看到达到分离效果

猜你喜欢

转载自blog.csdn.net/qq_34552886/article/details/79749150