public static SteeringOutput GetSteering(KinematicState ownKS, GameObject target) { SteeringOutput steering = new SteeringOutput(); if (!target) { return(null); } Vector3 directionToTarget; directionToTarget = target.transform.position - ownKS.position; directionToTarget.Normalize(); steering.linearAcceleration = directionToTarget * ownKS.maxAcceleration; return(steering); }
public static SteeringOutput GetSteering(KinematicState ownKS, SAlign info) { float l_requiredAngularSpeed; float l_requiredAngularAcceleration; float l_angleSize; float l_requiredRotation = info.m_target.rotation.eulerAngles.y - ownKS.m_orientation; if (l_requiredRotation < 0f) { l_requiredRotation += 360f; } if (l_requiredRotation > 180f) { l_requiredRotation = -(360f - l_requiredRotation); } l_angleSize = Mathf.Abs(l_requiredRotation); if (l_angleSize <= info.m_closeEnoughAngle) { return(NULL_STEERING); } if (l_angleSize > info.m_slowDownAngle) { l_requiredAngularSpeed = ownKS.m_maxAngularSpeed; } else { l_requiredAngularSpeed = ownKS.m_maxAngularSpeed * (l_angleSize - info.m_slowDownAngle); } l_requiredAngularSpeed *= Mathf.Sign(l_requiredRotation); l_requiredAngularAcceleration = (l_requiredAngularSpeed - ownKS.m_angularSpeed) / info.m_timeToDesiredAngularSpeed; l_requiredAngularAcceleration = MathExtent.Clip(l_requiredAngularAcceleration, ownKS.m_maxAngularAcceleration, true); SteeringOutput result = new SteeringOutput(); result.m_angularAcceleration = l_requiredAngularAcceleration; return(result); }
public static SteeringOutput GetSteering(KinematicState ownKS) { SteeringOutput result = new SteeringOutput(); Vector3 desiredDirection = Vector3.zero; float desiredAngularDirection = 0; // UP is MOVE FORWARD. // DOWN is MOVE BACKWARDS. if (Input.GetKey(KeyCode.UpArrow)) { desiredDirection += Utils.OrientationToVector(ownKS.orientation); } if (Input.GetKey(KeyCode.DownArrow)) { desiredDirection += -Utils.OrientationToVector(ownKS.orientation); } if (Input.GetKey(KeyCode.LeftArrow)) { desiredAngularDirection += 1f; } if (Input.GetKey(KeyCode.RightArrow)) { desiredAngularDirection += -1f; } // Beware: this part of the code tampers with the speed... if (desiredAngularDirection == 0) { ownKS.angularSpeed = 0; // stop!!! if (desiredDirection.magnitude < 0.01) { ownKS.linearVelocity = Vector3.zero; // stop!! } } result.linearAcceleration = desiredDirection * ownKS.maxAcceleration; result.angularAcceleration = desiredAngularDirection * ownKS.maxAngularAcceleration; return(result); }
public override SteeringOutput GetSteering() { // no KS? get it if (this.ownKS == null) { this.ownKS = GetComponent <KinematicState>(); } if (this.target == null) { Debug.Log("Null target in Seek of " + this.gameObject); } SteeringOutput result = Seek.GetSteering(this.ownKS, this.target); base.applyRotationalPolicy(rotationalPolicy, result, this.target); return(result); }
void Update() { //Get Accelerations SteeringOutput l_steering = GetSteering(); //Stop if there is no acceleration if (l_steering == null) { m_ownKS.m_linearVelocity = Vector3.zero; m_ownKS.m_angularSpeed = 0f; return; } float dt = Time.deltaTime; //Apply linear accelerations if (l_steering.m_linearActive) { m_ownKS.m_linearVelocity = m_ownKS.m_linearVelocity + l_steering.m_linearAcceleration * dt; m_ownKS.m_linearVelocity = MathExtent.Clip(m_ownKS.m_linearVelocity, m_ownKS.m_maxLinearSpeed); m_ownKS.m_position += m_ownKS.m_linearVelocity * dt + 0.5f * l_steering.m_linearAcceleration * dt * dt; transform.position = m_ownKS.m_position; } else { m_ownKS.m_linearVelocity = Vector3.zero; } //Apply angular Accelerations if (l_steering.m_angularActive) { m_ownKS.m_angularSpeed = m_ownKS.m_angularSpeed + l_steering.m_angularAcceleration * dt; m_ownKS.m_angularSpeed = MathExtent.Clip(m_ownKS.m_angularSpeed, m_ownKS.m_maxAngularSpeed, true); m_ownKS.m_orientation += m_ownKS.m_angularSpeed * dt + 0.5f * l_steering.m_angularAcceleration * dt * dt; transform.rotation = Quaternion.Euler(0f, m_ownKS.m_orientation, 0f); } else { m_ownKS.m_angularSpeed = 0f; } }
public static SteeringOutput GetSteering(KinematicState ownKS, string tag, float repulsionThreshold) { Vector3 directionToTarget; float distanceToTarget; float repulsionStrength = 0; int activeTargets = 0; SteeringOutput result = new SteeringOutput(); GameObject[] targets = GameObject.FindGameObjectsWithTag("Enemy"); foreach (GameObject target in targets) { if (target == ownKS.gameObject) { continue; } directionToTarget = target.transform.position - ownKS.position; distanceToTarget = directionToTarget.magnitude; if (distanceToTarget <= repulsionThreshold) { activeTargets++; repulsionStrength = ownKS.maxAcceleration * (repulsionThreshold - distanceToTarget) / repulsionThreshold; result.linearAcceleration = result.linearAcceleration - directionToTarget.normalized * repulsionStrength; } } if (activeTargets > 0) { if (result.linearAcceleration.magnitude > ownKS.maxAcceleration) { result.linearAcceleration = result.linearAcceleration.normalized * ownKS.maxAcceleration; } return(result); } else { return(nullSteering); } }
public static SteeringOutput GetSteering(KinematicState ownKS, GameObject attractor, float seekWeight = 0.2f, 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 = 023f) { SteeringOutput seekOutput = Seek.GetSteering(ownKS, attractor); SteeringOutput result = Flocking.GetSteering(ownKS, idTag, cohesionThreshold, repulsionThreshold, wanderRate); // beware, Flocking may return NULL_STEERING. In that case, just apply seek if (result == NULL_STEERING) { return(seekOutput); } result.linearAcceleration = result.linearAcceleration * (1 - seekWeight) + seekOutput.linearAcceleration * seekWeight; result.angularAcceleration = result.angularAcceleration * (1 - seekWeight) + seekOutput.angularAcceleration * seekWeight; return(result); }
public static SteeringOutput GetSteering(KinematicState ownKs, string idTag, float cohesionThreshold, float repulsionThreshold, float wanderRate, float vmWeight, float rpWeight, float coWeight, float wdWeight, GameObject target, float distance, float angle, float kpWeight) { SteeringOutput fl = Flocking.GetSteering(ownKs, idTag, cohesionThreshold, repulsionThreshold, wanderRate, vmWeight, rpWeight, coWeight, wdWeight); SteeringOutput kp = KeepPosition.GetSteering(ownKs, target, distance, angle); if (kp == NULL_STEERING) { return(fl); } fl.linearAcceleration = fl.linearAcceleration * (1 - kpWeight) + kp.linearAcceleration * kpWeight; // fl.linearAcceleration = fl.linearAcceleration.normalized * ownKs.maxAcceleration; return(fl); }
public virtual void applyLWYG(SteeringOutput steering) { if (ownKS.linearVelocity.magnitude > 0.001f) { // if linear velocity is very small, object is not moving (isn't going anywhere // hence it makes no sense to apply "look where you go" // Align with velocity. // create a surrogate target the orientation of which is that of my linear velocity SURROGATE_TARGET.transform.rotation = Quaternion.Euler(0, 0, Utils.VectorToOrientation(ownKS.linearVelocity)); SteeringOutput st = Align.GetSteering(ownKS, SURROGATE_TARGET); steering.angularAcceleration = st.angularAcceleration; steering.angularActive = st.angularActive; } else { steering.angularActive = false; } }
public static SteeringOutput GetSteering(KinematicState ownKS, GameObject target, float distance = 10.0f, float slowRadius = 20.0f, float disredSpeed = 0.1f, bool showWhishker = true, float lookAheadLength = 10f, float avoidDistance = 10f, float secondaryWhiskerAngle = 30f, float secondaryWhiskerRatio = 0.7f, string tag = "REPULSIVE", float repulsionTh = 8.0f, float repulsionWeight = 0.5f) { SteeringOutput linearRepulsion = LinearRepulsion.GetSteering(ownKS, tag, repulsionTh); SteeringOutput arrive = ArrivePlusAvoid.GetSteering(ownKS, target, distance, slowRadius, disredSpeed, showWhishker, lookAheadLength, avoidDistance, secondaryWhiskerAngle, secondaryWhiskerRatio); SteeringOutput result = new SteeringOutput(); if (linearRepulsion == NULL_STEERING) { return(arrive); } else if (arrive == NULL_STEERING) { return(linearRepulsion); } result.linearAcceleration = arrive.linearAcceleration * (1 - repulsionWeight) + linearRepulsion.linearAcceleration * repulsionWeight; return(result); }
public static SteeringOutput GetSteering(KinematicState ownKS, float WanderRate, float wanderRadius, float wanderOffset, ref float targetOrientation, float lookAheadLength, float avoidDistance, float secondaryWhiskerAngle, float secondaryWhiskerRatio, ref bool avoidActive, LayerMask avoidLayers, SphereCollider scanner) { SteeringOutput so = ObstacleAvoidance.GetSteering(ownKS, lookAheadLength, avoidDistance, secondaryWhiskerAngle, secondaryWhiskerRatio, avoidLayers, scanner); if (so == nullSteering) { if (avoidActive) { targetOrientation = ownKS.orientation; } avoidActive = false; return(Wander.GetSteering(ownKS, ref targetOrientation, WanderRate, wanderRadius, wanderOffset)); } else { avoidActive = true; return(so); } }
public static SteeringOutput GetSteering(KinematicState ownKS, GameObject target, string idTag, float RequiredDistance, float DesiredAngle, float RepulsionThreshold) { SteeringOutput rp = LinearRepulsion.GetSteering(ownKS, idTag, RepulsionThreshold); SteeringOutput Kep = My_KeepDistanceVersatile.GetSteering(ownKS, target, RequiredDistance, DesiredAngle); if (rp == null) { rp = new SteeringOutput(); } SteeringOutput result = new SteeringOutput(); result.linearAcceleration = rp.linearAcceleration * 0.6f + Kep.linearAcceleration * 0.4f; if (result.linearAcceleration.magnitude > ownKS.maxAcceleration) { result.linearAcceleration = result.linearAcceleration.normalized * ownKS.maxAcceleration; } return(result); }
private SteeringOutput KeyboardMove() { // no kinematic state required float x = Input.GetAxis("Horizontal"); float z = Input.GetAxis("Vertical"); Vector3 direction = new Vector3(x, 0, z); if (direction.magnitude < 0.05) { return(null); } // accelerate along direction SteeringOutput result = new SteeringOutput(); result.linearAcceleration = maxAcceleration * direction.normalized; return(result); }
public override SteeringOutput GetSteering() { SteeringOutput result = WanderPlusAvoid.GetSteering(ownKS, wanderRate, wanderRate, wanderOffset, ref targetOrientation, lookAheadLength, avoidDistance, secondaryWhiskerAngle, secondaryWhiskerRatio, ref avoidActive, avoidLayers, scanner); if (!surrogateTarget) { return(null); } if (ownKS.linearVelocity.magnitude > 0.001f) { surrogateTarget.transform.rotation = Quaternion.Euler(0, 0, VectorToOrientation(ownKS.linearVelocity)); SteeringOutput st = Align.GetSteering(ownKS, surrogateTarget); result.angularAcceleration = st.angularAcceleration; result.angularActive = st.angularActive; } else { result.angularActive = false; } return(result); }
public override SteeringOutput GetSteering() { SteeringOutput result = LinearRepulsion.GetSteering(this.ownKS, this.idTag, this.repulsionThreshold); if (!surrogateTarget) { return(null); } if (ownKS.linearVelocity.magnitude > 0.001f) { surrogateTarget.transform.rotation = Quaternion.Euler(0, 0, VectorToOrientation(ownKS.linearVelocity)); SteeringOutput st = Align.GetSteering(ownKS, surrogateTarget); result.angularAcceleration = st.angularAcceleration; result.angularActive = st.angularActive; } else { result.angularActive = false; } return(result); }
public override SteeringOutput GetSteering() { SteeringOutput result = Wander.GetSteering(ownKS, ref targetOrientation, wanderRate, wanderRadius, wanderOffset); if (!surrogateTarget) { return(null); } if (ownKS.linearVelocity.magnitude > 0.001f) { surrogateTarget.transform.rotation = Quaternion.Euler(0, 0, VectorToOrientation(ownKS.linearVelocity)); SteeringOutput st = Align.GetSteering(ownKS, surrogateTarget); result.angularAcceleration = st.angularAcceleration; result.angularActive = st.angularActive; } else { result.angularActive = false; } return(result); }
public override SteeringOutput GetSteering() { SteeringOutput result = ArrivePlusAvoid.GetSteering(ownKS, target, closeEnoughRadius, slowDownRadius, timeToDesiredSpeed, lookAheadLength, avoidDistance, secondaryWhiskerAngle, secondaryWhiskerRatio, avoidLayers, scanner, repulsionTag, repulsionThreshold, arriveWeight); if (!surrogateTarget) { return(null); } if (ownKS.linearVelocity.magnitude > 0.001f) { surrogateTarget.transform.rotation = Quaternion.Euler(0, 0, VectorToOrientation(ownKS.linearVelocity)); SteeringOutput st = Align.GetSteering(ownKS, surrogateTarget); result.angularAcceleration = st.angularAcceleration; result.angularActive = st.angularActive; } else { result.angularActive = false; } return(result); }
public override SteeringOutput GetSteering() { SteeringOutput result = Arrive.GetSteering(ownKS, target, closeEnoughRadius, slowDownRadius, timeToDesiredSpeed); if (!surrogateTarget) { return(null); } if (ownKS.linearVelocity.magnitude > 0.001f) { surrogateTarget.transform.rotation = Quaternion.Euler(0, 0, VectorToOrientation(ownKS.linearVelocity)); SteeringOutput st = Align.GetSteering(ownKS, surrogateTarget); result.angularAcceleration = st.angularAcceleration; result.angularActive = st.angularActive; } else { result.angularActive = false; } return(result); }
public static SteeringOutput GetSteering(KinematicState ownKS, GameObject target, float timeToDesiredVelocity = 0.1f) { KinematicState targetKS = target.GetComponent <KinematicState> (); if (targetKS == null) { Debug.LogError("Velocity matching requires a target with an accessible kinematic state "); return(null); } SteeringOutput result = new SteeringOutput(); // compute required acceleration to have same velocity result.linearAcceleration = (targetKS.linearVelocity - ownKS.linearVelocity) / timeToDesiredVelocity; // clip if necessary if (result.linearAcceleration.magnitude > ownKS.maxAcceleration) { result.linearAcceleration = result.linearAcceleration.normalized * ownKS.maxAcceleration; } return(result); }
public static SteeringOutput GetSteering(KinematicState ownKS, GameObject target, float distance = 10.0f, float angle = 180.0f, string tag = "REPULSIVE", float repulsionTh = 8.0f, float repulsiveWeight = 0.5f) { // compute both steerings SteeringOutput lr = LinearRepulsion.GetSteering(ownKS, tag, repulsionTh); SteeringOutput kp = KeepPosition.GetSteering(ownKS, target, distance, angle); // blend result SteeringOutput result = new SteeringOutput(); // (if one is SteeringBehaviour.NULL_STEERING return the other if (lr == NULL_STEERING) { return(kp); } else if (kp == NULL_STEERING) { return(lr); } // if none is SteeringBehaviour.NULL_STEERING blend with weights wlr and 1-wlr) result.linearAcceleration = kp.linearAcceleration * (1 - repulsiveWeight) + lr.linearAcceleration * repulsiveWeight; return(result); }
public static SteeringOutput GetSteering(KinematicState ownKS, GameObject target, float targetRadius, float slowDownRadius, float timeToDesiredSpeed) { SteeringOutput steering = new SteeringOutput(); Vector3 directionToTarget; float distanceToTarget; float desiredSpeed; Vector3 desiredVelocity; Vector3 requiredAcceleration; directionToTarget = target.transform.position - ownKS.position; distanceToTarget = directionToTarget.magnitude; if (distanceToTarget < targetRadius) { return(nullSteering); } if (distanceToTarget > slowDownRadius) { return(Seek.GetSteering(ownKS, target)); } desiredSpeed = ownKS.maxSpeed * (distanceToTarget / slowDownRadius); desiredVelocity = directionToTarget.normalized * desiredSpeed; requiredAcceleration = (desiredVelocity - ownKS.linearVelocity) / timeToDesiredSpeed; if (requiredAcceleration.magnitude > ownKS.maxAcceleration) { requiredAcceleration = requiredAcceleration.normalized * ownKS.maxAcceleration; } steering.linearAcceleration = requiredAcceleration; return(steering); }
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); }
private SteeringOutput Flocking(KinematicState own, string tag = "BOID") { float distanceToMate; KinematicState mate; Vector3 averageVelocity = Vector3.zero; int count = 0; // get all your mates... GameObject [] mates = GameObject.FindGameObjectsWithTag(tag); // and iterate to find average velocity for (int i = 0; i < mates.Length; i++) { // skip yourself if (mates[i].GetComponent <Steerings2>() == this) { continue; } mate = mates [i].GetComponent <Steerings2> ().ownKS; if (mate == null) { // this should never happen Debug.LogError("Incompatible mate in flocking"); continue; } // disregard distant mates. Consider cohesionThreshold distanceToMate = (mate.position - own.position).magnitude; if (distanceToMate > cohesionThreshold) { continue; } averageVelocity = averageVelocity + mate.linearVelocity; count++; } // end of iteration if (count > 0) { averageVelocity = averageVelocity / count; } // velocity matching with a surrogateTarget KinematicState surrogateTarget = new KinematicState(); surrogateTarget.linearVelocity = averageVelocity; SteeringOutput velMatching = VelocityMatching(own, surrogateTarget); SteeringOutput repulsion = LinearRepulsion(own, tag); SteeringOutput cohesion = Cohesion(own, tag); SteeringOutput wander = NaiveWander(own); //SteeringOutput wander = Wander (own, wanderTarget); //string status = "xxx "; // avoid nasty errors due to null objects if (velMatching == null) { velMatching = new SteeringOutput(); //status = status + "velmatching is null"; } if (repulsion == null) { repulsion = new SteeringOutput(); //status = status + " repulsion is null"; } if (cohesion == null) { cohesion = new SteeringOutput(); //status = status + " cohesion is null"; } if (wander == null) { wander = new SteeringOutput(); //status = status + " wander is null"; } //Debug.Log (status); SteeringOutput result = new SteeringOutput(); result.linearAcceleration = velMatching.linearAcceleration * 0.4f + repulsion.linearAcceleration * 2f + cohesion.linearAcceleration * 1f + wander.linearAcceleration * 0.5f; // clip if necessary if (result.linearAcceleration.magnitude > maxAcceleration) { result.linearAcceleration = result.linearAcceleration.normalized * maxAcceleration; } // add the angular acceleration provided by wander... result.angularAcceleration = wander.angularAcceleration; return(result); }
private SteeringOutput CollisionAvoidance(KinematicState own, string tag) { // avoids colliding against a moving spherical object float shortestTime = float.PositiveInfinity; KinematicState firstTarget = null; float firstMinSeparation = 0; float firstDistance = 0; Vector3 firstRelativePosition = Vector3.zero, relativePosition; Vector3 firstRelativeVelocity = Vector3.zero, relativeVelocity; float distance, minSeparation = 0f; float relativeSpeed; float timeToCollision; float radius, myRadius, firstRadius = 0; KinematicState target; // get all the targets // Steerings2 [] targets = GetComponents<Steerings2>(); //Steerings2 [] targets = FindObjectsOfType(typeof (Steerings2)) as Steerings2[]; GameObject [] tgts = GameObject.FindGameObjectsWithTag(tag); Steerings2 [] targets = new Steerings2[tgts.Length]; for (int i = 0; i < tgts.Length; i++) { targets [i] = tgts [i].GetComponent <Steerings2> (); } myRadius = Mathf.Max(GetComponent <Renderer> ().bounds.size.x / 2f, GetComponent <Renderer> ().bounds.size.y / 2f); // iterate thorough all the targets for (int i = 0; i < targets.Length; i++) { // do not consider yourself... if (targets [i].ownKS == own) { continue; } target = targets [i].ownKS; relativePosition = target.position - own.position; relativeVelocity = target.linearVelocity - own.linearVelocity; relativeSpeed = relativeVelocity.magnitude; timeToCollision = -(DotProduct(relativePosition, relativeVelocity)) / (relativeSpeed * relativeSpeed); if (float.IsNaN(timeToCollision)) { //Debug.Log ("No collisions"); continue; } if (timeToCollision < 0) { //Debug.Log ("No collisions. Object getting away"); continue; } if (timeToCollision > 10) { //Debug.Log ("Possible collision too distant in time"); continue; // don't mind distant collisions... } // is there going to be a collision at all? distance = relativePosition.magnitude; // current distance minSeparation = distance - relativeSpeed * timeToCollision; radius = Mathf.Max(targets [i].GetComponent <Renderer>().bounds.size.x / 2, targets [i].GetComponent <Renderer>().bounds.size.y / 2); if (minSeparation > (myRadius + radius)) { Debug.Log("No collisions. Object will not get too close"); continue; // there'll be no collision at all } Debug.Log("Collision Detected. Min separation is: " + minSeparation + " but required is: " + (myRadius + radius)); // is this the first object we're are going to collide with? if (timeToCollision < shortestTime) { // save data... shortestTime = timeToCollision; firstTarget = target; firstMinSeparation = minSeparation; firstDistance = distance; firstRelativePosition = relativePosition; firstRelativeVelocity = relativeVelocity; firstRadius = radius; } } // end of iteration; if (firstTarget == null) { return(null); } // if we're going to hit exactly or we're already colliding do the // steering based on the current position // else do the steering based on the future collision position if (firstMinSeparation <= 0 || firstDistance < (myRadius + firstRadius)) { relativePosition = firstRelativePosition; // relative position is direction to target } else { relativePosition = firstRelativePosition + firstRelativeVelocity * shortestTime; } Debug.DrawRay(transform.position, relativePosition, Color.red); SteeringOutput result = new SteeringOutput(); result.linearAcceleration = -relativePosition.normalized * maxAcceleration; return(result); }