简单的Boids算法
// 计算所有粒子的Boid运动
for (int i = 0; i < particleCount; i++)
{
Vector3 cohesion = Vector3.zero;
Vector3 alignment = Vector3.zero;
Vector3 separation = Vector3.zero;
int neighborCount = 0;
// 计算每个粒子的邻居
for (int j = 0; j < particleCount; j++)
{
if (i != j)
{
Vector3 distanceVector = particles[j].position - particles[i].position;
float distance = distanceVector.magnitude;
if (distance < neighborRadius)
{
cohesion += particles[j].position;
alignment += particles[j].velocity;
if (distance < separationDistance)
{
// 分离力与距离成反比
separation -= distanceVector.normalized / (distance + 0.001f);
}
neighborCount++;
}
}
}
// 计算合力
Vector3 force = Vector3.zero;
if (neighborCount > 0)
{
// 凝聚力:指向邻居粒子的平均位置
cohesion = (cohesion / neighborCount - particles[i].position).normalized;
// 对齐力:与邻居粒子速度方向一致
alignment = (alignment / neighborCount).normalized;
// 分离力:远离过近的邻居
separation = separation.normalized;
// 合并三个规则
force += cohesion * cohesionWeight;
force += alignment * alignmentWeight;
force += separation * separationWeight;
}
// 添加边界限制
if (boundaryRadius > 0)
{
float distanceToCenter = particles[i].position.magnitude;
if (distanceToCenter > boundaryRadius)
{
// 边界力:将粒子拉回中心
Vector3 centerDirection = -particles[i].position.normalized;
float boundaryInfluence = (distanceToCenter - boundaryRadius) / boundaryRadius;
force += centerDirection * boundaryInfluence * boundaryWeight;
}
}
// 计算目标速度
Vector3 targetVelocity = particles[i].velocity + force;
// 添加全局流动方向影响
targetVelocity += flowDirection.normalized * flowWeight;
// 添加随机扰动
targetVelocity += new Vector3(
Random.Range(-randomness, randomness),
Random.Range(-randomness, randomness),
Random.Range(-randomness, randomness)
);
// 限制最大速度
if (targetVelocity.magnitude > maxSpeed) {
targetVelocity = targetVelocity.normalized * maxSpeed;
}
// 使用平滑因子过渡到目标速度
particles[i].velocity = Vector3.Lerp(particles[i].velocity, targetVelocity, 1 - smoothingFactor);
}