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

en造数据结构与算法C# 用Unity实现简单的群组行为算法 之 聚集

还差一个对齐,不然就乱飞

分散算法请看上一篇文章:en造数据结构与算法C# 用Unity实现简单的群组行为算法 之 分散-CSDN博客

演示(在分散的基础上)

思路 

1.确定检测范围

其实,可以沿用上一篇章中分散的检测范围,为什么?

1.自然界中的鸟的分离和聚集是同时发生的,使用一个检测范围更加方便计算

2.因为每一只鸟身上都有一个群组脚本,所以可以把检测范围当作分割线来看,这样在检测范围内的鸟称作邻居,只有邻居才会受到影响,不然距离你十万八千里的外的鸟一把抓住,顷刻拉近也不合适,如图紫色线为关系连线

2.确定拉近位置

自然是邻居鸟的位置相加后的平均值了

3.确定力的合力与方向

原理和这张图大差不差,我就不再费事画了

上代码

分离出来的代码

cohesionForce = Vector3.zero; //凝聚力重设
    foreach (GameObject bird in separationNeighbors) {
        //设定分离力的方向
        Vector3 spForceDirection = (this.transform.position - bird.transform.position).normalized;
        if (spForceDirection.magnitude > 0) {
            separationForce += spForceDirection / spForceDirection.magnitude;
        }
        //得到鸟群位置(加起来的和)
        averagePosition += bird.transform.position;
    }

    //计算平均位置
    if (separationNeighbors.Count > 0) {
        averagePosition /= separationNeighbors.Count;
    }

    //设定凝聚力的方向
    Vector3 cohesionDirection = (averagePosition - transform.position).normalized;
    if (cohesionDirection.magnitude > 0) {
        cohesionForce += cohesionDirection;
    }

    //施加分离力
    rb.AddForce(separationForce, ForceMode.VelocityChange);
    //施加凝聚力
    rb.AddForce(cohesionForce, ForceMode.VelocityChange);
}

总和代码

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BoidsCode1 : MonoBehaviour {
    Rigidbody rb;
    //鸟群存储线性表
    public List<GameObject> separationNeighbors = new List<GameObject>();

    //separation分离  alignment对齐 cohesion凝聚
    public Vector3 separationForce = Vector3.zero;
    public Vector3 alignmentForce = Vector3.zero;
    public Vector3 cohesionForce = Vector3.zero;
    public Vector3 averagePosition = Vector3.zero;
    public Vector3 sumForce;

    //检测间隔
    public float checkInterval = 0.35f;
    //检测距离
    public float checkDistance = 2;

    private void Awake() {
        rb = GetComponent<Rigidbody>();
    }

    private void Start() {
        InvokeRepeating("CalcForce", 0, checkInterval);
    }

    //计算函数
    private void CalcForce() {
        //清空邻居鸟的列表
        separationNeighbors.Clear();
        //检测到范围内所有的鸟
        Collider[] colliders = Physics.OverlapSphere(transform.position, checkDistance);
        foreach (Collider collider in colliders) {
            if (collider != null && collider.gameObject != this.gameObject) {
                //添加到列表里面
                separationNeighbors.Add(collider.gameObject);
            }
        }

        //平均点位置为0
        averagePosition = Vector3.zero;
        separationForce = Vector3.zero; //分离力重设
        cohesionForce = Vector3.zero; //凝聚力重设
        alignmentForce = Vector3.zero; //对齐力重设

        foreach (GameObject bird in separationNeighbors) {
            //设定分离力的方向
            Vector3 spForceDirection = (this.transform.position - bird.transform.position).normalized;
            if (spForceDirection.magnitude > 0) {
                separationForce += spForceDirection / spForceDirection.magnitude;
            }
            //得到鸟群位置(加起来的和)
            averagePosition += bird.transform.position;
        }

        //计算平均位置
        if (separationNeighbors.Count > 0) {
            averagePosition /= separationNeighbors.Count;
        }

        //设定凝聚力的方向
        Vector3 cohesionDirection = (averagePosition - transform.position).normalized;
        if (cohesionDirection.magnitude > 0) {
            cohesionForce += cohesionDirection;
        }

        //施加分离力
        rb.AddForce(separationForce, ForceMode.VelocityChange);
        //施加凝聚力
        rb.AddForce(cohesionForce, ForceMode.VelocityChange);
    }
}


http://www.kler.cn/a/315782.html

相关文章:

  • 相机光学(四十二)——sony的HDR技术
  • Rust 所有权机制
  • python装饰器的使用以及私有化
  • K8s进阶使用
  • 初探鸿蒙:从概念到实践
  • golang分布式缓存项目 Day1 LRU 缓存淘汰策略
  • 数据库 | 索引
  • 记K8s组件harbor和kuboard故障恢复
  • 桶排序和计数排序(非比较排序算法)
  • QT实现升级进度条页面
  • 计算机毕业设计之:基于深度学习的路面检测系统(源码+部署文档+讲解)
  • frpc内网穿透
  • Card View 卡片视图
  • 软媒市场新探索:软文媒体自助发布,开启自助发稿新篇章
  • 算法练习题24——leetcode3296移山所需的最小秒数(二分模拟)
  • Mysql删库跑路,如何恢复数据?
  • HDFS性能优化高频面试题及答案
  • AWS 将 OpenSearch 纳入 Linux 基金会旗下
  • 四十一、完成内容添加功能(使用go测试方法)
  • 全栈项目小组【算法赛】题目及解题
  • How do you send files to the OpenAI API?
  • 1.量化第一步,搭建属于自己的金融数据库!
  • 鸿蒙设置,修改APP图标和名称
  • Android Choreographer 监控应用 FPS
  • 如何在Chrome最新浏览器中调用ActiveX控件?
  • 什么时候用synchronized,什么时候用Reentrantlock