예제 #1
0
        public override SteeringOutput GetSteering()
        {
            if (this.ownKS == null)
            {
                this.ownKS = GetComponent <KinematicState>();
            }

            return(Cohesion.GetSteering(this.ownKS, this.idTag, this.cohesionThreshold));
        }
예제 #2
0
        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);
        }
예제 #3
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);
        }
예제 #4
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);
        }