private Vector3 BuildOrientationBehaviorVelocity( FlockingNeighborDetector neighborDetector) { Vector3 summedNeighborVelocity = Vector3.zero; float summedNeighborConsiderationFractions = 0.0f; foreach (var neighbor in neighborDetector.GetNeighbors()) { var neighborFlightController = neighbor.flockingDesires.GetComponent <FlightController>(); if (neighborFlightController != null) { float neighborCurrentSpeed = IdlingSpeed; // neighborFlightController.CurrentSpeed; // BUG! Boids were feeding back into each other and creating explosive velocities, so for now we can't read CurrentSpeed for this. Vector3 neighborActualVelocity = (neighborCurrentSpeed * neighbor.flockingDesires.transform.forward); // Blend in our consideration of the neighbor so as to avoid twitching when they're first sighted. Vector3 neighborWeightedVelocity = (neighbor.currentConsiderationFraction * neighborActualVelocity); summedNeighborVelocity += neighborWeightedVelocity; summedNeighborConsiderationFractions += neighbor.currentConsiderationFraction; } } Vector3 meanNeighborVelocity = (summedNeighborVelocity / Mathf.Max(summedNeighborConsiderationFractions, 1.0f)); return(meanNeighborVelocity); }
private Vector3 BuildCohesionBehaviorVelocity( FlockingNeighborDetector neighborDetector) { Vector3 summedSelfToNeighborDeltas = Vector3.zero; float summedNeighborConsiderationFractions = 1.0f; // NOTE: We're including ourselves in the center-of-mass calculation. foreach (var neighbor in neighborDetector.GetNeighbors()) { Vector3 selfToNeighborDelta = (neighbor.flockingDesires.transform.position - transform.position); // Blend in our consideration of the neighbor so as to avoid twitching when they're first sighted. summedSelfToNeighborDeltas += (neighbor.currentConsiderationFraction * selfToNeighborDelta); summedNeighborConsiderationFractions += neighbor.currentConsiderationFraction; } Vector3 selfToCenterOfMass = (summedSelfToNeighborDeltas / summedNeighborConsiderationFractions); float selfToCenterOfMassDistance = selfToCenterOfMass.magnitude; float initialNeighborThrottleFraction = Mathf.Clamp01(summedNeighborConsiderationFractions); float peakSatisfactionThrottleFraction = Mathf.Clamp01(selfToCenterOfMassDistance / CohesionSatisfactionFalloffDistance); float throttleFraction = (initialNeighborThrottleFraction * peakSatisfactionThrottleFraction); float throttleSpeed = (CohesionMaxSpeed * throttleFraction); Vector3 cohesionDirection = (selfToCenterOfMass / Mathf.Max(selfToCenterOfMassDistance, Mathf.Epsilon)); Vector3 cohesionVelocity = (throttleSpeed * cohesionDirection); return(cohesionVelocity); }
private Vector3 BuildAvoidanceBehaviorVelocity( FlockingNeighborDetector neighborDetector) { Vector3 naiveNeighborhoodAvoidanceVelocity = Vector3.zero; foreach (var neighbor in neighborDetector.GetNeighbors()) { Vector3 selfToNeighborDirection = Vector3.zero; float normalizedDistanceToNeighbor = 0.0f; // Choose our direction and distance, but explicitly handling edge cases such as sharing the same // position as our neighbor, which do terrible things (eg. NaN-vectors) when left unhandled. { Vector3 selfToNeighborDelta = (neighbor.flockingDesires.transform.position - transform.position); float selfToNeighborDistance = selfToNeighborDelta.magnitude; if (selfToNeighborDistance <= AvoidanceRandomPanicDistance) { selfToNeighborDirection = Random.onUnitSphere; normalizedDistanceToNeighbor = AvoidanceRandomPanicDistance; } else { selfToNeighborDirection = (selfToNeighborDelta / selfToNeighborDistance); normalizedDistanceToNeighbor = (selfToNeighborDistance / AvoidanceBaseDistance); } } float neighborAvoidanceSpeed = Mathf.Min( (AvoidanceBaseSpeed / normalizedDistanceToNeighbor), AvoidanceMaxSpeed); // Blend in our consideration of the neighbor so as to avoid twitching when they're first sighted. naiveNeighborhoodAvoidanceVelocity += ( (neighbor.currentConsiderationFraction * neighborAvoidanceSpeed) * (-1 * selfToNeighborDirection)); } float naiveNeighborhoodAvoidanceSpeed = naiveNeighborhoodAvoidanceVelocity.magnitude; Vector3 neighborhoodAvoidanceDirection = (naiveNeighborhoodAvoidanceVelocity / Mathf.Max(naiveNeighborhoodAvoidanceSpeed, Mathf.Epsilon)); Vector3 finalNeighborhoodAvoidanceVelocity = (Mathf.Min(naiveNeighborhoodAvoidanceSpeed, AvoidanceMaxSpeed) * neighborhoodAvoidanceDirection); return(finalNeighborhoodAvoidanceVelocity); }