自学内容网 自学内容网

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);
    }
}


原文地址:https://blog.csdn.net/2301_77947509/article/details/142345925

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!