unity Boid算法 鱼群跟随 代码实现
时间: 2024-12-27 18:21:41 浏览: 5
### 关于在 Unity 中使用 Boid 算法实现鱼群跟随行为
为了实现在 Unity 中模拟鱼群的自然游动效果,可以采用经典的 Boid 群体运动模型。该算法由 Craig Reynolds 提出,通过三个简单规则来指导个体的行为:分离(Separation),对准(Alignment),聚拢(Cohesion)[^1]。
#### 实现思路
- **分离 (Separation)** :当两个物体靠得太近时会产生排斥力使它们分开。
- **对准 (Alignment)** :尝试匹配邻近群体成员的速度方向。
- **聚拢 (Cohesion)** :趋向于向邻居们的平均位置移动。
这些原则可以通过调整权重参数来进行微调以获得更逼真的视觉效果。
#### 示例代码
下面是一个简单的基于上述原理编写的 C# 脚本用于控制 GameObject 表现为鱼类并遵循 Boid 规则:
```csharp
using System.Collections.Generic;
using UnityEngine;
public class Fish : MonoBehaviour {
public float maxSpeed = 3f; //最大速度
private Vector3 velocity; //当前速度矢量
void Update() {
List<Fish> nearbyFish = FindNearbyFish();
if(nearbyFish.Count > 0){
ApplyRules(nearbyFish);
}
Move();
}
void ApplyRules(List<Fish> others) {
Vector3 separationForce = Separation(others);
Vector3 alignmentForce = Alignment(others);
Vector3 cohesionForce = Cohesion(others);
velocity += separationForce + alignmentForce + cohesionForce;
velocity.Normalize();
velocity *= maxSpeed;
}
void Move(){
transform.Translate(velocity * Time.deltaTime, Space.World);
}
/// <summary>
/// 寻找附近的其他鱼对象
/// </summary>
/// <returns></returns>
List<Fish> FindNearbyFish(){
Collider[] hitColliders = Physics.OverlapSphere(transform.position, viewRadius);
List<Fish> result = new List<Fish>();
foreach(var item in hitColliders){
var otherFish = item.GetComponent<Fish>();
if(otherFish != null && otherFish != this){
result.Add(otherFish);
}
}
return result;
}
/// <summary>
/// 计算分离力
/// </summary>
/// <param name="others"></param>
/// <returns></returns>
Vector3 Separation(List<Fish> others){
Vector3 steer = Vector3.zero;
int count = 0;
foreach(Fish f in others){
float d = Vector3.Distance(f.transform.position,transform.position);
if(d < minDistance){
Vector3 diff = transform.position - f.transform.position;
diff.Normalize();
steer += diff / d;
++count;
}
}
if(count > 0){
steer /= count;
steer.Normalize();
steer *= maxSpeed;
steer -= velocity;
steer = Vector3.ClampMagnitude(steer,maxSteeringForce);
}
return steer;
}
/// <summary>
/// 对齐力计算
/// </summary>
/// <param name="others"></param>
/// <returns></returns>
Vector3 Alignment(List<Fish> others){
Vector3 avgVelocity = Vector3.zero;
int count = 0;
foreach(Fish f in others){
avgVelocity += f.velocity;
++count;
}
if(count > 0){
avgVelocity /= count;
avgVelocity.Normalize();
avgVelocity *= maxSpeed;
Vector3 steer = avgVelocity - velocity;
steer = Vector3.ClampMagnitude(steer,maxSteeringForce);
return steer;
}else{
return Vector3.zero;
}
}
/// <summary>
/// 向心力计算
/// </summary>
/// <param name="others"></param>
/// <returns></returns>
Vector3 Cohesion(List<Fish> others){
Vector3 centerOfMass = Vector3.zero;
int count = 0;
foreach(Fish f in others){
centerOfMass += f.transform.position;
++count;
}
if(count > 0){
centerOfMass /= count;
return Seek(centerOfMass);
}else{
return Vector3.zero;
}
}
/// <summary>
/// 追求目标点的方向
/// </summary>
/// <param name="targetPosition"></param>
/// <returns></returns>
Vector3 Seek(Vector3 targetPosition){
Vector3 desired = targetPosition - transform.position;
desired.Normalize();
desired *= maxSpeed;
Vector3 steer = desired - velocity;
steer = Vector3.ClampMagnitude(steer,maxSteeringForce);
return steer;
}
}
```
此脚本定义了一个 `Fish` 类,其中包含了基本属性以及应用 Boids 规则的方法。需要注意的是,在实际项目中可能还需要考虑边界条件处理、性能优化等问题[^2]。
阅读全文