示例#1
0
文件: Seek.cs 项目: NoctisRB/Eddy
        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);
        }
示例#2
0
        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);
        }
示例#3
0
        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);
        }
示例#4
0
        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);
        }
示例#5
0
        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;
            }
        }
示例#6
0
        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);
            }
        }
示例#7
0
        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);
        }
示例#11
0
        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);
        }
示例#13
0
        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);
        }
示例#14
0
        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);
        }
示例#15
0
        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);
        }
示例#16
0
        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);
        }
示例#17
0
        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);
        }
示例#18
0
文件: Arrive.cs 项目: NoctisRB/Eddy
        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);
        }
示例#19
0
        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);
        }
示例#20
0
        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);
        }
示例#21
0
文件: Arrive.cs 项目: NoctisRB/Eddy
        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);
        }
示例#22
0
        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);
        }
示例#23
0
        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);
        }
示例#24
0
        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);
        }
示例#25
0
        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);
        }