鱼群算法又称为群组行为,比如说走路,但是不能很规律的执行走路,要有人工智能的感觉的去执行走路,更加真实的去模拟现实,并且人与人之间不能拥挤到一起。常用与鸟群,鱼群,人群等 鱼群算法的规则: ——组的总控制器      ——控制组中的每个成员自身  一:前言
 ——分隔规则: 尽量避免与临近成员过于拥挤
 ——对准规则: 尽量与临近成员的平均方向一致
 ——内聚规则: 尽量朝临近成员的中心移动
二:效果演示

三:代码
 
using UnityEngine; using System.Collections.Generic;  /// <summary> /// 组的总控制器(挂载到组长身上,可以是玩家也可以是要跟随的物体) /// </summary> public class GroupController : MonoBehaviour {     private static List<GroupController> groups;//所有组      [Header("组中成员的层")]     public LayerMask mask;     [Header("组中成员的ID")]     public int groupID = 0;     [Header("组中成员始终保持的距离")]     public float keepDis;     [Header("组中成员始终保持的距离的权重")]     public float keepWeight;     [Header("多少距离算离得太近")]     public float targetCloseDistance;     [Header("组中成员停止移动的距离")]     public float stopDis;      /// <summary>     /// 得到成员属于哪个组     /// </summary>     /// <param name="index">成员ID</param>     /// <returns></returns>     public static GroupController GetGroup(int index)     {         if (groups == null)         {             groups = new List<GroupController>(FindObjectsOfType(typeof(GroupController)) as GroupController[]);         }          for (int i = 0; i < groups.Count; i++)         {             if (groups[i].groupID == index)             {                 return groups[i];             }         }         throw new System.Exception("没有找到相同ID的组");     } } 
using UnityEngine;  /// <summary> /// 挂载到组中的每个成员身上 /// </summary> public class GroupMember : MonoBehaviour {     private GroupController myGroup;//当前成员的GroupController组件      //速度和移动相关参数     private float targetSpeed;     private float speed;     private float currentSpeed;     private Vector3 myMovement;      [Header("属于的组ID")]     public int groupId;     [Header("移动速度")]     public float moveSpeed;     [Header("旋转速度")]     public float rotateSpeed;      private void Start()     {         myGroup = GroupController.GetGroup(groupId);     }      void Update()     {         Vector3 dis = myGroup.transform.position - transform.position;         Vector3 dir = dis.normalized;          //重新计算目的地距离权重         if (dis.magnitude < myGroup.targetCloseDistance)         {             dir *= dis.magnitude / myGroup.targetCloseDistance;         }         dir += GetAroundMemberInfo();//获取周围组的移动          //计算移动速度         if ((myGroup.transform.position - transform.position).magnitude < myGroup.stopDis)         {             targetSpeed = 0;         }         else         {             targetSpeed = moveSpeed;         }         speed = Mathf.Lerp(speed, targetSpeed, 2 * Time.deltaTime);          //————————————————————移动         transform.right = -dir;         Move(dir, speed);     }      /// <summary>     /// 得到周围成员的信息     /// </summary>     /// <returns></returns>     private Vector3 GetAroundMemberInfo()     {         Collider2D[] c = Physics2D.OverlapCircleAll(transform.position, myGroup.keepDis, myGroup.mask);//获取周围成员         Vector3 dis;         Vector3 v1 = Vector3.zero;         Vector3 v2 = Vector3.zero;         for (int i = 0; i < c.Length; i++)         {             GroupMember otherMember = c[i].GetComponent<GroupMember>();             dis = transform.position - otherMember.transform.position;//距离             v1 += dis.normalized * (1 - dis.magnitude / myGroup.keepDis);//查看与周围成员的距离             v2 += otherMember.myMovement;//查看周围成员移动方向              Debug.DrawLine(transform.position, otherMember.transform.position, Color.yellow);         }         return v1.normalized * myGroup.keepWeight + v2.normalized;//添加权重因素     }      /// <summary>     /// 移动     /// </summary>     /// <param name="_dir">方向</param>     /// <param name="_speed">速度</param>     private void Move(Vector3 _dir, float _speed)     {         Vector3 finialDirection = _dir.normalized;         float finialSpeed = _speed, finialRotate = 0;         float rotateDir = Vector3.Dot(finialDirection, transform.right);         float forwardDir = Vector3.Dot(finialDirection, transform.forward);          if (forwardDir < 0)         {             rotateDir = Mathf.Sign(rotateDir);         }         if (forwardDir < -0.2f)         {             finialSpeed = Mathf.Lerp(currentSpeed, -_speed * 8, 4 * Time.deltaTime);         }          //——————————防抖         if (forwardDir < 0.98f)         {             finialRotate = Mathf.Clamp(rotateDir * 180, -rotateSpeed, rotateSpeed);         }          finialSpeed *= Mathf.Clamp01(_dir.magnitude);         finialSpeed *= Mathf.Clamp01(1 - Mathf.Abs(rotateDir) * 0.8f);          transform.Translate(Vector3.left * finialSpeed * Time.deltaTime);         transform.Rotate(Vector3.forward * finialRotate * Time.deltaTime);          currentSpeed = finialSpeed;         myMovement = _dir * finialSpeed;     }  }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算
 官方软件产品操作指南 (170)
官方软件产品操作指南 (170)