因为还没写聚集并且材质没有设置摩擦系数,所以出现了这种刚体受力得到初速度却无法减少,从而乱飞的情况
本教程部分代码师承于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);}
}