AI_群组行为

using System.Collections.Generic;
using UnityEngine;

public class CrowAI : MonoBehaviour {
    //当前速度 
    public float speed = 10;
    public Vector3 velocity = Vector3.forward;
    private Vector3 startVelocity;//初始化当前速度
    public Transform target;//目标点
    //总力
    public Vector3 sumForce = Vector3.zero;
    //质量
    public float m = 3;

    //分离的力
    public float sparationDistance = 3;   //分离的距离
    public List<GameObject> sparationNeighbors = new List<GameObject>();
    public float sparationWeight = 1; //权重
    public Vector3 sparationForce = Vector3.zero;

    //队列的力
    public float alignmentDistance = 4;
    public List<GameObject> alignmentNeighbors = new List<GameObject>();
    public float alignmentWeight = 1; //权重
    public Vector3 alignmentForce = Vector3.zero;

    //聚集的力
    public float cohesionWeight = 3;//权重
    public Vector3 cohesionForce = Vector3.zero;
    //间隔几秒检测一次
    public float checkInterval = 0.2f;

    private Animation anim;
    public float animRandom = 2;
    void Start()
    {
        target = GameObject.Find("target").transform;
        startVelocity = velocity;
        //0 秒后调用 CalcForce() 方法,并且之后每隔 checkInterval 秒调用一次 CalcForce() 方法
        InvokeRepeating("CalcForce", 0, checkInterval);
        anim = GetComponentInChildren<Animation>();
        Invoke("Playanim", Random.Range(0, animRandom));
    }
    void Playanim() {
        anim.Play();
    }

    void CalcForce() {
        //计算之前先归零
        sumForce = Vector3.zero;
        sparationForce = Vector3.zero;
        alignmentForce = Vector3.zero;
        cohesionForce = Vector3.zero;

        //先清空集合
        sparationNeighbors.Clear();
        Collider[] colliders = Physics.OverlapSphere(transform.position, sparationDistance);
        foreach (Collider c in colliders)
        {
            //判断该物体近的邻居
            if (c!=null && c.gameObject!=this.gameObject)
            {
                sparationNeighbors.Add(c.gameObject);
            }
        }

        //1.计算分离的力
        foreach (GameObject neighbor in sparationNeighbors)
        {
            Vector3 dir = transform.position - neighbor.transform.position;
            sparationForce += dir.normalized / dir.magnitude;
        }
        //如果附近有物体
        if (sparationNeighbors.Count > 0)
        {
            //得到分离的力
            sparationForce *= sparationWeight;
            //得到的力赋值给总力
            sumForce += sparationForce;
        }

        //2.计算队列的力(整体一个前进的力)
        alignmentNeighbors.Clear();
        colliders = Physics.OverlapSphere(transform.position, alignmentDistance);
        foreach (Collider c in colliders)
        {
            if (c!=null &&c.gameObject !=this.gameObject)
            {
                alignmentNeighbors.Add(c.gameObject);
            }
        }
        //计算邻居的平均朝向
        Vector3 avgDir = Vector3.zero;
        //朝向的总和
        foreach (GameObject n in alignmentNeighbors)
        {
            avgDir += n.transform.forward;
        }
        if (alignmentNeighbors.Count >0)
        {
            //得到平均数
            avgDir /= alignmentNeighbors.Count;
            //得到相对方向
            alignmentForce = avgDir = transform.forward;
            alignmentForce *= alignmentWeight;
            //得到的力赋值给总力
            sumForce += alignmentForce;
        }

        //3.聚集的力
        if (alignmentNeighbors.Count > 0)
        {
            Vector3 center = Vector3.zero;
            foreach (GameObject n in alignmentNeighbors)
            {
                center += n.transform.position;
            }
            center /= alignmentNeighbors.Count;
            Vector3 dirToCenter = center - transform.position;
            cohesionForce += dirToCenter.normalized * velocity.magnitude;
            cohesionForce *= cohesionWeight;
            sumForce += cohesionForce;
        }

        //4.保持恒定飞行速度的力
        Vector3 enginForce = velocity.normalized * startVelocity.magnitude;
        sumForce += enginForce * 0.1f;
        //4.保持恒定目标飞行的效果
        Vector3 targetDir = target.position - transform.position;
        sumForce += (targetDir.normalized - transform.forward)*speed;
    }


    void Update () {
        //加速度(根据牛顿第二定律)
        Vector3 a = sumForce / m;
        //计算出速度
        velocity += a * Time.deltaTime;
        //物体运行
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.LookRotation(velocity), Time.deltaTime*3);
        transform.Translate(transform.forward * Time.deltaTime * velocity .magnitude, Space.World);
    }
}

 

转载于:https://www.cnblogs.com/mclll520/p/8618425.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值