UnityAI行为------群组行为CraigReynold算法

结合上一篇文章讲述群组行为的算法,这篇是替换实现,更加清晰。

FlockController的行为很简单,它在运行时生成boid的行为,更新群组的中心及群组的平均速度

public class FlockController : MonoBehaviour {

    public float minVelocity = 1;
    public float maxVeclocity = 8;
    public int flockSize = 20;

    public float centerWeight = 1;
    public float velocityWeight = 1;
    public float separationWeight = 1;
    public float followWeight = 1;
    public float randomizeWeight = 1;
    public Flock perfab;
    public Transform target;
    public Vector3 flockCenter;
    public Vector3 flockVelocity;
    public ArrayList flockList = new ArrayList();

	void Start () {
        for(int i = 0; i < flockSize; i++)
        {
            Flock flock = Instantiate(perfab,transform.position,transform.rotation) as Flock;
            flock.transform.parent = transform;
            flock.controller = this;
            flockList.Add(flock);
        }
	}
	/*
     先声明实现群组算法所需的所有属性,再基于输入的群组大小生成boid对象,和上次一样,
         */

	void Update () {
        Vector3 center = Vector3.zero;
        Vector3 velocity = Vector3.zero;
        foreach(Flock flock in flockList)
        {
            center += flock.transform.localPosition;
            velocity += flock.transform.GetComponent<Rigidbody>().velocity;
        }
        flockCenter = center / flockSize;
        flockVelocity = velocity / flockSize;
	}
    /*
     在Update方法中,保持更新群组的平均中心和速度,这些值来自于我们的boid对象,它们可以用来调整与控制者的凝聚与队列属性
     */
}

 

下面是具有TargetMoement脚本的Target实体,稍后我们将创建这个脚本,我们选择一个附近的随机的目标点,并向其移动。当我们到达该点附近时,再选择一个新的点。这时所有boid都将跟随这个目标。

public class TargetMovement : MonoBehaviour {

    public Vector3 bound;
    public float speed = 100.0f;
    private Vector3 initialPosition;
    private Vector3 nextMovementPoint;

	void Start () {
        initialPosition = transform.position;
        CalculateNextMovementPoint();

    }
	
    void CalculateNextMovementPoint()
    {
        float posX = Random.Range(initialPosition.x - bound.x,initialPosition.x + bound.x);
        float posY = Random.Range(initialPosition.y - bound.y,initialPosition.y + bound.y);
        float posZ = Random.Range(initialPosition.z - bound.z,initialPosition.z + bound.z);
        nextMovementPoint = initialPosition + new Vector3(posX,posY,posZ);
    }

	void Update () {
        transform.Translate(Vector3.forward * speed * Time.deltaTime);
        transform.rotation = Quaternion.Slerp(transform.rotation,Quaternion.LookRotation(nextMovementPoint - transform.position),1.0f * Time.deltaTime);
        if(Vector3.Distance(nextMovementPoint,transform.position)<=10.0f)
        {
            CalculateNextMovementPoint();
        }
	}
}

public class Flock : MonoBehaviour {

    public FlockController controller;
    private Rigidbody rigidbody;
    private void Awake()
    {
        rigidbody = transform.GetComponent<Rigidbody>();
    }

    private void Start()
    {
        controller = transform.parent.GetComponent<FlockController>();
    }

    private void Update()
    {
        if(controller)
        {
            Vector3 relativePos = steer() * Time.deltaTime;
            if(relativePos != Vector3.zero)
            {
                rigidbody.velocity = relativePos;
            }

            float speed = rigidbody.velocity.magnitude;
            if(speed > controller.maxVeclocity)
            {
                rigidbody.velocity = rigidbody.velocity.normalized * controller.maxVeclocity;
            }else if(speed < controller.minVelocity)
            {
                rigidbody.velocity = rigidbody.velocity.normalized * controller.minVelocity;
            }
        }
    }

    private Vector3 steer()
    {
        Vector3 center = controller.flockCenter - transform.localPosition;
        Vector3 velocity = controller.flockVelocity - rigidbody.velocity;
        Vector3 follow = controller.target.localPosition - transform.localPosition;
        Vector3 separation = Vector3.zero;
        foreach(Flock flock in controller.flockList)
        {
            if(flock != this)
            {
                Vector3 ralativePos = transform.localPosition - flock.transform.localPosition;
                separation += ralativePos / (ralativePos.sqrMagnitude);
            }
        }
        Vector3 randomize = new Vector3((Random.value * 2) - 1,(Random.value * 2) - 1,(Random.value * 2) - 1);
        randomize.Normalize();
        return (controller.centerWeight * center + controller.velocityWeight * velocity + controller.separationWeight * separation + controller.followWeight * follow + controller.randomizeWeight * randomize);
    }
}



  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值