• 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);
        }
    }
  • 相关阅读:
    flume自定义source
    flume自定义sink之文件
    - Exception follows. org.apache.flume.FlumeException: java.net.BindException: Address already in use
    flume自定义sink之mysql
    Vue 【事件&样式】样式
    选择器
    rem
    表格和表单
    双飞翼布局、圣杯布局
    三栏布局
  • 原文地址:https://www.cnblogs.com/mclll520/p/8618425.html
Copyright © 2020-2023  润新知