// SEPARATION: Steering to avoid colliding or crowing with other flockmates private Vector3 CalculateSeparation(int boidIndex) { ComputeBoid boid = m_boids[boidIndex]; if (boid.GetNeighbourCount() == 0) { return(Vector3.zero); } Vector3 separationForce = Vector3.zero; Vector3 boidPosition = boid.transform.position; float separationDistSqr = m_separationValue * m_separationValue; foreach (ComputeBoid neighbour in boid.IterateNeighbours()) { Vector3 difference = boidPosition - neighbour.transform.position; float distanceSqr = difference.sqrMagnitude; if (distanceSqr < separationDistSqr) { // Needs separating Vector3 separate = difference; separate.Normalize(); separate = separate / distanceSqr; separationForce += separate; } } return(separationForce); }
// ALIGNMENT: Steering to move with the average heading of flockmates private Vector3 CalculateAlignment(int boidIndex) { ComputeBoid boid = m_boids[boidIndex]; if (boid.GetNeighbourCount() == 0) { return(Vector3.zero); } Vector3 alignmentForce = Vector3.zero; Vector3 sumHeading = Vector3.zero; foreach (ComputeBoid neighbour in boid.IterateNeighbours()) { sumHeading = neighbour.GetBoidVelocity().normalized; } alignmentForce = sumHeading / boid.GetNeighbourCount(); return(alignmentForce); }
private void CalculateRules(int boidIndex, ref Vector3 sepForce, ref Vector3 alignForce, ref Vector3 cohForce) { ComputeBoid boid = m_boids[boidIndex]; if (boid.GetNeighbourCount() == 0) { return; } Vector3 boidPosition = boid.transform.position; sepForce = Vector3.zero; alignForce = Vector3.zero; cohForce = Vector3.zero; float separationDistSqr = m_separationValue * m_separationValue; Vector3 sumHeading = Vector3.zero; Vector3 averagePosition = Vector3.zero; foreach (ComputeBoid neighbour in boid.IterateNeighbours()) { sumHeading = neighbour.GetBoidVelocity().normalized; averagePosition += neighbour.transform.position; Vector3 difference = boidPosition - neighbour.transform.position; float distanceSqr = difference.sqrMagnitude; if (distanceSqr < separationDistSqr) { // Needs separating Vector3 separate = difference; separate.Normalize(); separate = separate / distanceSqr; sepForce += separate; } } alignForce = sumHeading / boid.GetNeighbourCount(); averagePosition /= boid.GetNeighbourCount(); cohForce = averagePosition - m_boids[boidIndex].transform.position; }
// COHESION: Steering to move towards the average position of flockmates private Vector3 CalculateCohesion(int boidIndex) { ComputeBoid boid = m_boids[boidIndex]; if (boid.GetNeighbourCount() == 0) { return(Vector3.zero); } Vector3 cohesionForce = Vector3.zero; Vector3 averagePosition = Vector3.zero; foreach (ComputeBoid neighbour in boid.IterateNeighbours()) { averagePosition += neighbour.transform.position; } averagePosition /= boid.GetNeighbourCount(); cohesionForce = averagePosition - m_boids[boidIndex].transform.position; return(cohesionForce); }