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

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

        因为还没写聚集并且材质没有设置摩擦系数,所以出现了这种刚体受力得到初速度却无法减少,从而乱飞的情况

        本教程部分代码师承于siki学院siki老师的人工智能编程这一案例,我认为自己的水平有限,老师的写法太过高级,所以就写了一下自己想着能实现的算法,没想到还真成了,嘻嘻

演示

第一版

第二版

思路

1.确定检测范围

自然是用到Unity的范围检测了,unity保姆级教程之 射线检测_unity 射线-CSDN博客

2.存起来邻居鸟

自然用到线性表,你问我什么是线性表?

恩造数据结构与算法c# 用数组实现List-CSDN博客

不过嘛,这里用c#官方造好的轮子即可,List<T>

3.确定力的合力与方向

自然用到向量的知识,注意朝向哦

unity保姆级教程之向量篇_unity 向量-CSDN博客

4.施加力

第一版演示的是用直接刚体加力,不过这样会造成飞的太快,并且加力大小也不会根据鸟之间的距离发生改变,所以就小小优化了一下

上代码

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

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

    //separation分离  aliganment对齐 cohesion凝聚
    public Vector3 separationForce = Vector3.zero;
    public Vector3 aliganmentForce = Vector3.zero;
    public Vector3 cohesionForce = 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()
        {
        //清空邻居鸟的列表
        seprationNeighbors.Clear();
        //检测到范围内所有的鸟
        Collider[] colliders = Physics.OverlapSphere(transform.position, checkDistance);
        foreach (Collider collider in colliders) {
            if (collider!=null && collider!=this.gameObject)
            {
                //添加到列表里面
                seprationNeighbors.Add(collider.gameObject);
            }
        }
        separationForce = Vector3.zero;
        foreach (GameObject brid in seprationNeighbors) { 
            //设定方向
            Vector3 forceDirection =(this.transform.position - brid.transform.position).normalized;
            //直接施加力以作实验
            //rb.AddForce(forceDirection,ForceMode.Impulse);
            //或 这样写,好处就是可以根据距离累加力
            if (forceDirection.magnitude > 0) {
                separationForce += forceDirection / forceDirection.magnitude;
            }
        }
            rb.AddForce(separationForce, ForceMode.Impulse);
    }
}


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

相关文章:

  • vue-router的push和replace的区别
  • 丑数动态规划
  • 微信小程序 === 使用腾讯地图选点
  • 使用 npm 安装 Yarn
  • Essential Cell Biology--Fifth Edition--Chapter one (6)
  • SpringBoot整合Mybatis-Plus实践汇总
  • 运算符两边的数据类型
  • [数据库] Redis学习笔记(一):介绍、安装、基本数据结构、常见命令
  • 在Windows系统上安装的 zstd C++ 库
  • ADB 安装教程:如何在 Windows、macOS 和 Linux 上安装 Android Debug Bridge
  • Spring 事务与 MySQL 事务:深度解析与实战指南
  • 使用docker创建zabbix服务器
  • 2024华为杯E题成品文章已出!
  • 使用Crawler实例进行网页内容抓取
  • 制造企业为何需要PLM系统?PLM系统解决方案对制造业重要性分析
  • Python Web 分布式系统性能监控与链路追踪技术解析
  • vue实现鼠标滚轮控制页面横向滑动
  • 你知道吗?制造手机芯片的关键竟然是一台“打印机”?
  • Redis配置文件详解(上)
  • 【报告阅读】chatgpt-o1 技术报告阅读 | 新的迭代开始了~
  • 大数据新视界 --大数据大厂之数据清洗工具 OpenRefine 实战:清理与转换数据
  • Java 入门指南:获取对象的内存地址
  • 美信监控易的优势:长期稳定运行
  • java se 快速入门
  • 自制网络连接工具(支持tcpudp,客户端服务端)
  • SDK(1.1note)