public override SteeringOutput GetSteering() { if (this.ownKS == null) { this.ownKS = GetComponent <KinematicState>(); } return(Cohesion.GetSteering(this.ownKS, this.idTag, this.cohesionThreshold)); }
public override SteeringOutput GetSteering() { if (this.ownKS == null) { this.ownKS = GetComponent <KinematicState>(); } SteeringOutput result = Cohesion.GetSteering(this.ownKS, this.idTag, this.cohesionThreshold); base.applyRotationalPolicy(rotationalPolicy, result, null); return(result); }
public static SteeringOutput GetSteering(KinematicState ownKS, string idTag = "BOID", float cohesionThreshold = 40f, float repulsionThreshold = 10f, float wanderRate = 10f, float vmWeight = 0.08f, float rpWeight = 0.46f, float coWeight = 0.23f, float wdWeight = 0.23f) { float distanceToBoid; KinematicState boidKS; Vector3 averageVelocity = Vector3.zero; int count = 0; SteeringOutput result = new SteeringOutput(); // get all the other boids GameObject [] boids = GameObject.FindGameObjectsWithTag(idTag); // ... and iterate to find average velocity foreach (GameObject boid in boids) { // skip yourself if (boid == ownKS.gameObject) { continue; } boidKS = boid.GetComponent <KinematicState> (); if (boidKS == null) { // this should never happen but you never know Debug.Log("Incompatible mate in flocking. Flocking mates must have a kinematic state attached: " + boid); continue; } // disregard distant boids distanceToBoid = (boidKS.position - ownKS.position).magnitude; if (distanceToBoid > Math.Max(cohesionThreshold, repulsionThreshold)) { continue; } averageVelocity = averageVelocity + boidKS.linearVelocity; count++; } // end of iteration to find average velocity if (count > 0) { averageVelocity = averageVelocity / count; } else { // if no boid is close enough (count==0) there's no flocking to be performed so return NULL_STEERING // or just apply some wandering... return(NaiveWander.GetSteering(ownKS, wanderRate)); } SURROGATE_TARGET.GetComponent <KinematicState> ().linearVelocity = averageVelocity; SteeringOutput vm = VelocityMatching.GetSteering(ownKS, SURROGATE_TARGET); // (in normal conditions) this does NOT return NULL_STEERING SteeringOutput rp = LinearRepulsion.GetSteering(ownKS, idTag, repulsionThreshold); // this MAY return NULL_STEERING SteeringOutput co = Cohesion.GetSteering(ownKS, idTag, cohesionThreshold); // this MAY return NULL_STEERING result.linearAcceleration = vm.linearAcceleration * vmWeight + rp.linearAcceleration * rpWeight + // if rp==NULL_STEERING linearAcceleration is Vector3.zero co.linearAcceleration * coWeight; // id for co. // and now let's add some wandering to make things less predictable (yet more stable) SteeringOutput wd = NaiveWander.GetSteering(ownKS, wanderRate); result.linearAcceleration += wd.linearAcceleration * wdWeight; // adjust to maxAcceleration result.linearAcceleration = result.linearAcceleration.normalized * ownKS.maxAcceleration; return(result); }
public static SteeringOutput GetSteering(KinematicState ownKS, string idTag = "BOID", float cohesionThreshold = 40f, float repulsionThreshold = 10f, float wanderRate = 10f) { float distanceToBoid; KinematicState boid; Vector3 averageVelocity = Vector3.zero; int count = 0; // get all the other boids GameObject [] boids = GameObject.FindGameObjectsWithTag(idTag); // ... and iterate to find average velocity for (int i = 0; i < boids.Length; i++) { // skip yourself if (boids[i] == ownKS.gameObject) { continue; } boid = boids [i].GetComponent <KinematicState> (); if (boid == null) { // this should never happen but you never know Debug.Log("Incompatible mate in flocking. Flocking mates must have a kinematic state attached: " + boids[i]); continue; } // disregard distant boids distanceToBoid = (boid.position - ownKS.position).magnitude; if (distanceToBoid > Math.Max(cohesionThreshold, repulsionThreshold)) { continue; } averageVelocity = averageVelocity + boid.linearVelocity; count++; } // end of iteration to find average velocity if (count > 0) { averageVelocity = averageVelocity / count; } else { return(null); } // if no boid is close enough (count==0) there's no flocking to be performed so return null // could also apply some wandering if (surrogateTarget == null) { surrogateTarget = new GameObject("surrogate target for Flocking"); surrogateKS = surrogateTarget.AddComponent <KinematicState> (); } surrogateKS.linearVelocity = averageVelocity; SteeringOutput vm = VelocityMatching.GetSteering(ownKS, surrogateTarget); // (in normal conditions) this does NOT return null SteeringOutput rp = LinearRepulsion.GetSteering(ownKS, idTag, repulsionThreshold); // this MAY return null SteeringOutput co = Cohesion.GetSteering(ownKS, idTag, cohesionThreshold); // this MAY return null // avoid nasty problems due to null references if (rp == null) { rp = new SteeringOutput(); } if (co == null) { co = new SteeringOutput(); } SteeringOutput result = new SteeringOutput(); result.linearAcceleration = vm.linearAcceleration * 0.4f + rp.linearAcceleration * 2f + co.linearAcceleration * 1f; // and now let's add some wandering to make things less predictable SteeringOutput wd = VeryNaiveWander.GetSteering(ownKS, wanderRate); result.linearAcceleration += wd.linearAcceleration * 1f; // clip if necessary if (result.linearAcceleration.magnitude > ownKS.maxAcceleration) { result.linearAcceleration = result.linearAcceleration.normalized * ownKS.maxAcceleration; } return(result); }