当前位置: 首页 > news >正文

简单的鱼群算法实现

鱼群算法根据鱼类的活动特点, 提出了一种基于动物行为的自治体寻优模式

鱼的聚群行为: 鱼在游动过程中会自然地聚集成群, 这也是为了保证群体的生存和躲避危害而形成的
一种生活习性 鱼群的形成也是一种突现的生动示例, Reyno lds 认为鸟类和鱼类的群集的形成并不需要
一个领头者, 只需要每只鸟或每条鱼遵循一些局部的相互作用规则即可, 然后群集现象作为整体模式从个
体的局部的相互作用中突现出来 Reyno lds 所采用的规则有三条: 1) 分隔规则: 尽量避免与临近伙伴过于
拥挤; 2) 对准规则: 尽量与临近伙伴的平均方向一致; 3) 内聚规则: 尽量朝临近伙伴的中心移动


我使用了其中1,2 条规则简单实现了下坦克分队移动的模拟
逻辑如下
1 监测自己与目标的距离和方向
2 监测周围单位的距离和移动方向
3 两个方向相加获得相量方向进行移动

工程下载(unity3d package)
http://pan.baidu.com/s/1F17yQ

简单的鱼群算法实现
简单的鱼群算法实现

简单的鱼群算法实现

简单的鱼群算法实现

代码如下

组:

 

 

public class TankGroup : MonoBehaviour {

         private static List tankGroups;//所有组

        

         public LayerMask mask;//成员层

         public int groupID=0;//id

         public float keepDistance=10, keepWeight=1;//成员保持距离和保持距离权重

         public float targetCloseDistance=20,targetWeight=1.25f, moveWeight=0.8f;//距离目标距离,距离目标权重和成员移动权重

}

坦克成员

 

 

public class TankBehaviour : MonoBehaviour {

         private const float minMoveCheck=0.2f;

        

         public int groupId=0;//组 id

         public float moveSpeed=5, rotateSpeed=20;//移动旋转速度

        

         public Vector3 position{

                   get{return transform.position;}

         }

        

         public Vector3 movement{

                   get{returnmyMovement;}

         }

        

         private Vector3 myMovement=Vector3.zero;

         private TankGroup myGroup;

         private float tgtSpeed=0, speed=0, currentSpeed;

        

         public void SetGroup(int index){

                   myGroup=TankGroup.GetTankGroup(index);

         }

        

         // Use this for initialization

         void Start () {

                   SetGroup(groupId);

         }

        

         // Update is called once per frame

         void Update () {

                   Vector3 displacement=myGroup.targetPosition-position;//获取目标距离

                   Vector3 direction=displacement.normalized*myGroup.targetWeight;//方向*权重

                  

                   if(displacement.magnitude//重新计算目的地距离权重

                           direction*=displacement.magnitude/myGroup.targetCloseDistance;

                  

                   direction+=GetGroupMovement();//获取周围组的移动

                  

                   if((myGroup.targetPosition-position).magnitude//计算移动速度

                            tgtSpeed=0;

                   else

                            tgtSpeed=moveSpeed;

                  

                   speed=Mathf.Lerp(speed,tgtSpeed,2*Time.deltaTime);

                  

                   Drive(direction, speed);//移动

         }

        

         private Vector3 GetGroupMovement(){

                   Collider[] c=Physics.OverlapSphere(position,myGroup.keepDistance,myGroup.mask);//获取周围成员

                   Vector3 dis,v1=Vector3.zero, v2=Vector3.zero;

                   for(int i=0; i

                            TankBehaviour otherTank=c[i].GetComponent();

                            dis=position-otherTank.position;//距离

                            v1+=dis.normalized*(1-dis.magnitude/myGroup.keepDistance);//查看与周围单位的距离

                            v2+=otherTank.movement;//查看周围单位移动方向

                           

                            Debug.DrawLine(position, otherTank.position, Color.yellow);

                   }

                  

                   return v1.normalized*myGroup.keepWeight+v2.normalized*myGroup.moveWeight;//添加权重因素

         }

        

         private void Drive(Vector3 direction, float spd){

                   Vector3 finialDirection=direction.normalized;

                  float finialSpeed=spd, finialRotate=0;

                   floatrotateDir=Vector3.Dot(finialDirection,transform.right);

                   floatforwardDir=Vector3.Dot(finialDirection,transform.forward);

                  

                   if(forwardDir<<span style="color:#00DBE6">0)

                            rotateDir=Mathf.Sign(rotateDir);

                           

                   if(forwardDir<<span style="color:#00DBE6">-0.2f)

                            finialSpeed=Mathf.Lerp(currentSpeed,-spd*8,4*Time.deltaTime);

                  

                   if(forwardDir<<span style="color:#00DBE6">0.98f)//防抖

                            finialRotate=Mathf.Clamp(rotateDir*180,-rotateSpeed, rotateSpeed);

                  

                   finialSpeed*=Mathf.Clamp01(direction.magnitude);

                   finialSpeed*=Mathf.Clamp01(1-Mathf.Abs(rotateDir)*0.8f);

                  

                   transform.Translate(Vector3.forward*finialSpeed*Time.deltaTime);

                   transform.Rotate(Vector3.up*finialRotate*Time.deltaTime);

                  

                   currentSpeed=finialSpeed;

                   myMovement=direction*finialSpeed;

         }

        

}

http://www.xdnf.cn/news/812899.html

相关文章:

  • 数据采集网关的功能和应用场景
  • 用户'NT AUTHORITY/NETWORK SERVICE' 登录失败解决办法
  • adb shell 命令详解
  • 大学课程 | 《微机原理与接口技术》知识点总结
  • RadHat搭建内网YUM源服务器
  • 网络优化的实践: 如何优化网络架构设计
  • 如何扩容C盘?6种扩展C盘方法!
  • 【分享】School Rumble校园迷糊大王PSP姐姐事件+PS2游戏第一,二学期【带VNR翻译教程】...
  • ActionListener的用法
  • 第一章 1.The Basic (CCNA)
  • 最新海康摄像机、NVR、流媒体服务器、回放取流RTSP地址规则说明
  • [转]缓冲区溢出攻击(含示例)
  • Google原生输入法LatinIME词库构建流程分析(二)
  • 硬件开发笔记(二十六):AD21导入电感原理图库、封装库和3D模型
  • BT下载原理简介
  • android 五大应用开发框架,2024年最新html5移动开发即学即用网盘
  • 在HTML网页中设置弹出窗口的办法
  • 计算机网络选择填空题
  • Google IPV6 地址
  • Eclipse值得安装的插件
  • 无线传感器网络的时钟同步估计问题(Matlab代码实现)
  • 论坛集
  • 10本java书籍,每一本都是经典,从菜鸡到大神
  • 全类别通用!提升11%!CAReg:超越FSAD实现少样本异常检测!
  • 科大讯飞和neospeech tts哪个更好
  • Win7系统提示找不到sethc.exe文件的解决办法
  • 2022 Typecho PureLove简单纯净主题
  • java证书验证失败_java – 如何解决“证书无效且无法用于验证此网站的身份”错误?...
  • WPF入门教程系列七——布局之WrapPanel与StackPanel(二)
  • 安卓广播使用时的ANR问题,onReceive的生命周期为10秒