//--------------------- AccumulateForce ----------------------------------
    //
    //  This function calculates how much of its max steering force the
    //  vehicle has left to apply and then applies that amount of the
    //  force to add.
    //------------------------------------------------------------------------
    bool AccumulateForce(FlockEntity entity, ref Vector3 RunningTot, Vector3 ForceToAdd)
    {
        //calculate how much steering force the vehicle has used so far
        float MagnitudeSoFar = RunningTot.magnitude;

        //calculate how much steering force remains to be used by this vehicle
        float MagnitudeRemaining = entity.m_MaxForce - MagnitudeSoFar;

        //return false if there is no more force left to use
        if (MagnitudeRemaining <= 0.0)
        {
            return(false);
        }

        //calculate the magnitude of the force we want to add
        float MagnitudeToAdd = ForceToAdd.magnitude;

        //if the magnitude of the sum of ForceToAdd and the running total
        //does not exceed the maximum force available to this vehicle, just
        //add together. Otherwise add as much of the ForceToAdd vector is
        //possible without going over the max.
        if (MagnitudeToAdd < MagnitudeRemaining)
        {
            RunningTot += ForceToAdd;
        }

        else
        {
            //add it to the steering force
            RunningTot += (Vector3.Normalize(ForceToAdd) * MagnitudeRemaining);
        }

        return(true);
    }
    //---------------------------- Separation --------------------------------
    //
    // this calculates a force repelling from the other neighbors
    //------------------------------------------------------------------------
    Vector3 Separation(FlockEntity entity, List <FlockEntity> nearby)
    {
        Vector3 SteeringForce = Vector3.zero;

        for (int a = 0; a < nearby.Count; ++a)
        {
            //make sure this agent isn't included in the calculations and that
            //the agent being examined is close enough. ***also make sure it doesn't
            //include the evade target ***
            if (nearby[a].Tagged)
            {
                Vector3 ToAgent = entity.transform.position - nearby[a].transform.position;

                if (ToAgent.sqrMagnitude < 0.001f)
                {
                    // if next to randomly move away from
                    SteeringForce += Random.insideUnitSphere;
                }
                else
                {
                    //scale the force inversely proportional to the agents distance
                    //from its neighbor.
                    SteeringForce += Vector3.Normalize(ToAgent) / ToAgent.magnitude;
                }
            }
        }

        return(SteeringForce);
    }
    //---------------------------- Alignment ---------------------------------
    //
    //  returns a force that attempts to align this agents heading with that
    //  of its neighbors
    //------------------------------------------------------------------------
    Vector3 Alignment(FlockEntity entity, List <FlockEntity> nearby)
    {
        //used to record the average heading of the neighbors
        Vector3 AverageHeading = Vector3.zero;

        //used to count the number of vehicles in the neighborhood
        int NeighborCount = 0;

        //iterate through all the tagged vehicles and sum their heading vectors
        for (int a = 0; a < nearby.Count; ++a)
        {
            //make sure *this* agent isn't included in the calculations and that
            //the agent being examined  is close enough ***also make sure it doesn't
            //include any evade target ***
            if (nearby[a].Tagged)
            {
                AverageHeading += nearby[a].Heading;
                ++NeighborCount;
            }
        }

        //if the neighborhood contained one or more vehicles, average their
        //heading vectors.
        if (NeighborCount > 0)
        {
            AverageHeading /= (float)NeighborCount;
            AverageHeading -= entity.Heading;
        }

        return(AverageHeading);
    }
    //-------------------------------- Cohesion ------------------------------
    //
    //  returns a steering force that attempts to move the agent towards the
    //  center of mass of the agents in its immediate area
    //------------------------------------------------------------------------
    Vector3 Cohesion(FlockEntity entity, List <FlockEntity> nearby)
    {
        //first find the center of mass of all the agents
        Vector3 CenterOfMass  = Vector3.zero;
        Vector3 SteeringForce = Vector3.zero;

        int NeighborCount = 0;

        //iterate through the neighbors and sum up all the position vectors
        for (int a = 0; a < nearby.Count; ++a)
        {
            if (nearby[a].Tagged)
            {
                CenterOfMass += nearby[a].transform.position;
                ++NeighborCount;
            }
        }

        if (NeighborCount > 0)
        {
            //the center of mass is the average of the sum of positions
            CenterOfMass /= (float)NeighborCount;

            //now seek towards that position
            SteeringForce = Seek(entity, CenterOfMass);
        }

        //the magnitude of cohesion is usually much larger than separation or
        //allignment so it usually helps to normalize it.
        return(SteeringForce.normalized);
    }
    //--------------------- AccumulateForce ----------------------------------
    //
    //  This function calculates how much of its max steering force the
    //  vehicle has left to apply and then applies that amount of the
    //  force to add.
    //------------------------------------------------------------------------
    bool AccumulateForce(FlockEntity entity, ref Vector3 RunningTot, Vector3 ForceToAdd)
    {
        //calculate how much steering force the vehicle has used so far
        float MagnitudeSoFar = RunningTot.magnitude;

        //calculate how much steering force remains to be used by this vehicle
        float MagnitudeRemaining = entity.m_MaxForce - MagnitudeSoFar;

        //return false if there is no more force left to use
        if (MagnitudeRemaining <= 0.0) return false;

        //calculate the magnitude of the force we want to add
        float MagnitudeToAdd = ForceToAdd.magnitude;

        //if the magnitude of the sum of ForceToAdd and the running total
        //does not exceed the maximum force available to this vehicle, just
        //add together. Otherwise add as much of the ForceToAdd vector is
        //possible without going over the max.
        if (MagnitudeToAdd < MagnitudeRemaining)
        {
            RunningTot += ForceToAdd;
        }

        else
        {
            //add it to the steering force
            RunningTot += (Vector3.Normalize(ForceToAdd) * MagnitudeRemaining);
        }

        return true;
    }
    public Vector3 Calc(FlockEntity entity, List <FlockEntity> nearbyEntities, Vector3 target)
    {
        //reset the steering force
        m_SteeringForce = Vector3.zero;

        // summing method
        return(CalculateWeightedSum(entity, nearbyEntities, target));
    }
    public Vector3 Calc(FlockEntity entity, List<FlockEntity> nearbyEntities, Vector3 target)
    {
        //reset the steering force
        m_SteeringForce = Vector3.zero;

        // summing method
        return CalculateWeightedSum(entity, nearbyEntities, target);
    }
    //---------------------- CalculateWeightedSum ----------------------------
    //
    //  this simply sums up all the active behaviors X their weights and
    //  truncates the result to the max available steering force before
    //  returning
    //------------------------------------------------------------------------
    Vector3 CalculateWeightedSum(FlockEntity entity, List <FlockEntity> nearby, Vector3 target)
    {
        if (On(Behaviour.separation))
        {
            m_SteeringForce += Separation(entity, nearby) * entity.WeightSeparation;
        }

        if (On(Behaviour.allignment))
        {
            m_SteeringForce += Alignment(entity, nearby) * entity.WeightAlignment;
        }

        if (On(Behaviour.cohesion))
        {
            m_SteeringForce += Cohesion(entity, nearby) * entity.WeightCohesion;
        }

        if (On(Behaviour.wander))
        {
            m_SteeringForce += Wander(entity) * entity.WeightWander;
        }

        if (On(Behaviour.seek))
        {
            m_SteeringForce += Seek(entity, target) * entity.WeightSeek;
        }

        if (On(Behaviour.flee))
        {
            m_SteeringForce += Flee(entity, target) * entity.WeightFlee;
        }

        /*
         * if (On(Behaviour.arrive))
         * {
         *  m_vSteeringForce += Arrive(m_pVehicle->World()->Crosshair(), m_Deceleration) * m_dWeightArrive;
         * }
         *
         * if (On(Behaviour.pursuit))
         * {
         *  Debug.Assert(m_pTargetAgent1, "pursuit target not assigned");
         *
         *  m_vSteeringForce += Pursuit(m_pTargetAgent1) * m_dWeightPursuit;
         * }
         *
         * if (On(offset_pursuit))
         * {
         *  Debug.Assert(m_pTargetAgent1, "pursuit target not assigned");
         *  Debug.Assert(!m_vOffset.isZero(), "No offset assigned");
         *
         *  m_vSteeringForce += OffsetPursuit(m_pTargetAgent1, m_vOffset) * m_dWeightOffsetPursuit;
         * }
         */
        Vector3.ClampMagnitude(m_SteeringForce, entity.m_MaxForce);

        return(m_SteeringForce);
    }
示例#9
0
        // Start is called before the first frame update
        protected virtual void Start()
        {
            _fsm = new FSM <States>();

            FlockEntity flockEntity = this.GetComponent <FlockEntity>();

            SwimmingState <States> swimming = new SwimmingState <States>(_fsm, this, flockEntity);
            InFlockState <States>  inflock  = new InFlockState <States>(_fsm, this, flockEntity);

            swimming.AddTransition(States.IN_FLOCK, inflock);
            inflock.AddTransition(States.SWIMMING, swimming);

            _fsm.SetInit(swimming);
        }
示例#10
0
    void Start()
    {
        m_BasicSP = new BasicSP <FlockEntity>(new Vector3i(SpatialDivide, SpatialDivide, SpatialDivide), new Vector3(-50f, -50f, -50f), new Vector3(50f, 50f, 50f));

        for (int i = 0; i < Quantity; i++)
        {
            FlockEntity entity = Instantiate(EntityPrefab).GetComponent <FlockEntity>();
            m_Entities.Add(entity);

            // Group them under manager so they dont swamp the scene hierarchy
            entity.transform.parent   = transform;
            entity.m_Velocity         = Vector3.forward;
            entity.transform.position = Random.insideUnitSphere * 10;
        }
    }
    Vector3 Flee(FlockEntity entity, Vector3 TargetPos)
    {
        //only flee if the target is within 'panic distance'. Work in distance
        //squared space.

        /* const double PanicDistanceSq = 100.0f * 100.0;
         * if (Vec2DDistanceSq(m_pVehicle->Pos(), target) > PanicDistanceSq)
         * {
         * return Vector2D(0,0);
         * }
         */

        Vector3 DesiredVelocity = Vector3.Normalize(entity.Position - TargetPos) * entity.m_MaxSpeed;

        return(DesiredVelocity - entity.m_Velocity);
    }
        public override Vector3 CalculateDirection(List <Transform> context)
        {
            Vector3 direction = Vector3.zero;

            FlockEntity entity       = this.GetComponent <FlockEntity>();
            Vector3     centerOfMass = Vector3.zero;

            if (context.Count > 0)
            {
                foreach (Transform item in context)
                {
                    centerOfMass += item.position;
                }

                centerOfMass /= context.Count;

                direction = centerOfMass - this.transform.position;
            }

            return(direction);
        }
    Vector3 Wander(FlockEntity entity)
    {
        //this behavior is dependent on the update rate, so this line must
        //be included when using time independent framerate.
        float JitterThisTimeSlice = m_WanderJitter * Time.deltaTime;

        //first, add a small random vector to the target's position
        m_WanderTarget += Random.insideUnitSphere * JitterThisTimeSlice;

        //reproject this new vector back on to a unit circle
        m_WanderTarget.Normalize();

        //increase the length of the vector to the same as the radius
        //of the wander circle
        m_WanderTarget *= m_WanderRadius;

        //move the target into a position WanderDist in front of the agent
        Vector3 target = m_WanderTarget + new Vector3(0, 0, m_WanderDistance);

        target = entity.transform.rotation * target;

        //and steer towards it
        return(target);
    }
    //---------------------- CalculatePrioritized ----------------------------
    //
    //  this method calls each active steering behavior in order of priority
    //  and acumulates their forces until the max steering force magnitude
    //  is reached, at which time the function returns the steering force
    //  accumulated to that  point
    //------------------------------------------------------------------------
    Vector3 CalculatePrioritized(FlockEntity entity, List <FlockEntity> nearby, Vector3 target)
    {
        Vector3 force;

        /*
         * if (On(Behaviour.wall_avoidance))
         * {
         *  force = WallAvoidance(m_pVehicle->World()->Walls()) *
         *          m_dWeightWallAvoidance;
         *
         *  if (!AccumulateForce(entity, ref m_vSteeringForce, force)) return m_SteeringForce;
         * }
         *
         * if (On(Behaviour.obstacle_avoidance))
         * {
         *  force = ObstacleAvoidance(m_pVehicle->World()->Obstacles()) *
         *          m_dWeightObstacleAvoidance;
         *
         *  if (!AccumulateForce(entity, ref m_vSteeringForce, force)) return m_SteeringForce;
         * }
         *
         * if (On(Behaviour.evade))
         * {
         *  assert(m_pTargetAgent1 && "Evade target not assigned");
         *
         *  force = Evade(m_pTargetAgent1) * m_dWeightEvade;
         *
         *  if (!AccumulateForce(entity, ref m_vSteeringForce, force)) return m_SteeringForce;
         * }
         */

        if (On(Behaviour.flee))
        {
            force = Flee(entity, target) * entity.WeightFlee;

            if (!AccumulateForce(entity, ref m_SteeringForce, force))
            {
                return(m_SteeringForce);
            }
        }



        //these next three can be combined for flocking behavior (wander is
        //also a good behavior to add into this mix)

        if (On(Behaviour.separation))
        {
            force = Separation(entity, nearby) * entity.WeightSeparation;

            if (!AccumulateForce(entity, ref m_SteeringForce, force))
            {
                return(m_SteeringForce);
            }
        }

        if (On(Behaviour.allignment))
        {
            force = Alignment(entity, nearby) * entity.WeightAlignment;

            if (!AccumulateForce(entity, ref m_SteeringForce, force))
            {
                return(m_SteeringForce);
            }
        }

        if (On(Behaviour.cohesion))
        {
            force = Cohesion(entity, nearby) * entity.WeightCohesion;

            if (!AccumulateForce(entity, ref m_SteeringForce, force))
            {
                return(m_SteeringForce);
            }
        }

        if (On(Behaviour.seek))
        {
            force = Seek(entity, target) * entity.WeightSeek;

            if (!AccumulateForce(entity, ref m_SteeringForce, force))
            {
                return(m_SteeringForce);
            }
        }

        /*
         * if (On(Behaviour.arrive))
         * {
         *  force = Arrive(m_pVehicle->World()->Crosshair(), m_Deceleration) * m_dWeightArrive;
         *
         *  if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce;
         * }
         */
        if (On(Behaviour.wander))
        {
            force = Wander(entity) * entity.WeightWander;

            if (!AccumulateForce(entity, ref m_SteeringForce, force))
            {
                return(m_SteeringForce);
            }
        }

        /*
         * if (On(Behaviour.pursuit))
         * {
         *  assert(m_pTargetAgent1 && "pursuit target not assigned");
         *
         *  force = Pursuit(m_pTargetAgent1) * m_dWeightPursuit;
         *
         *  if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce;
         * }
         *
         * if (On(Behaviour.offset_pursuit))
         * {
         *  assert(m_pTargetAgent1 && "pursuit target not assigned");
         *  assert(!m_vOffset.isZero() && "No offset assigned");
         *
         *  force = OffsetPursuit(m_pTargetAgent1, m_vOffset);
         *
         *  if (!AccumulateForce(m_vSteeringForce, force)) return m_SteeringForce;
         * }
         *
         * if (On(Behaviour.interpose))
         * {
         *  Debug.Assert(m_pTargetAgent1 && m_pTargetAgent2, "Interpose agents not assigned");
         *
         *  force = Interpose(m_pTargetAgent1, m_pTargetAgent2) * m_dWeightInterpose;
         *
         *  if (!AccumulateForce(m_vSteeringForce, force)) return m_vSteeringForce;
         * }
         *
         * if (On(Behaviour.hide))
         * {
         *  assert(m_pTargetAgent1 && "Hide target not assigned");
         *
         *  force = Hide(m_pTargetAgent1, m_pVehicle->World()->Obstacles()) * m_dWeightHide;
         *
         *  if (!AccumulateForce(m_vSteeringForce, force)) return m_SteeringForce;
         * }
         *
         *
         * if (On(Behaviour.follow_path))
         * {
         *  force = FollowPath() * m_dWeightFollowPath;
         *
         *  if (!AccumulateForce(m_vSteeringForce, force)) return m_SteeringForce;
         * }
         */
        return(m_SteeringForce);
    }
    Vector3 Seek(FlockEntity entity, Vector3 TargetPos)
    {
        Vector3 DesiredVelocity = Vector3.Normalize(TargetPos - entity.Position) * entity.m_MaxSpeed;

        return(DesiredVelocity - entity.m_Velocity);
    }
示例#16
0
 private void Awake()
 {
     _flock = GetComponent <FlockEntity>();
     _model = GetComponent <Model>();
 }
    //---------------------------- Alignment ---------------------------------
    //
    //  returns a force that attempts to align this agents heading with that
    //  of its neighbors
    //------------------------------------------------------------------------
    Vector3 Alignment(FlockEntity entity, List<FlockEntity> nearby)
    {
        //used to record the average heading of the neighbors
        Vector3 AverageHeading = Vector3.zero;

        //used to count the number of vehicles in the neighborhood
        int NeighborCount = 0;

        //iterate through all the tagged vehicles and sum their heading vectors
        for (int a = 0; a < nearby.Count; ++a)
        {
            //make sure *this* agent isn't included in the calculations and that
            //the agent being examined  is close enough ***also make sure it doesn't
            //include any evade target ***
            if (nearby[a].Tagged)
            {
                AverageHeading += nearby[a].Heading;
                ++NeighborCount;
            }
        }

        //if the neighborhood contained one or more vehicles, average their
        //heading vectors.
        if (NeighborCount > 0)
        {
            AverageHeading /= (float)NeighborCount;
            AverageHeading -= entity.Heading;
        }

        return AverageHeading;
    }
    //---------------------- CalculatePrioritized ----------------------------
    //
    //  this method calls each active steering behavior in order of priority
    //  and acumulates their forces until the max steering force magnitude
    //  is reached, at which time the function returns the steering force
    //  accumulated to that  point
    //------------------------------------------------------------------------
    Vector3 CalculatePrioritized(FlockEntity entity, List<FlockEntity> nearby, Vector3 target)
    {
        Vector3 force;
        /*
        if (On(Behaviour.wall_avoidance))
        {
            force = WallAvoidance(m_pVehicle->World()->Walls()) *
                    m_dWeightWallAvoidance;

            if (!AccumulateForce(entity, ref m_vSteeringForce, force)) return m_SteeringForce;
        }

        if (On(Behaviour.obstacle_avoidance))
        {
            force = ObstacleAvoidance(m_pVehicle->World()->Obstacles()) *
                    m_dWeightObstacleAvoidance;

            if (!AccumulateForce(entity, ref m_vSteeringForce, force)) return m_SteeringForce;
        }

        if (On(Behaviour.evade))
        {
            assert(m_pTargetAgent1 && "Evade target not assigned");

            force = Evade(m_pTargetAgent1) * m_dWeightEvade;

            if (!AccumulateForce(entity, ref m_vSteeringForce, force)) return m_SteeringForce;
        }
        */

        if (On(Behaviour.flee))
        {
            force = Flee(entity, target) * entity.WeightFlee;

            if (!AccumulateForce(entity, ref m_SteeringForce, force)) return m_SteeringForce;
        }

        //these next three can be combined for flocking behavior (wander is
        //also a good behavior to add into this mix)

        if (On(Behaviour.separation))
        {
            force = Separation(entity, nearby) * entity.WeightSeparation;

            if (!AccumulateForce(entity, ref m_SteeringForce, force)) return m_SteeringForce;
        }

        if (On(Behaviour.allignment))
        {
            force = Alignment(entity, nearby) * entity.WeightAlignment;

            if (!AccumulateForce(entity, ref m_SteeringForce, force)) return m_SteeringForce;
        }

        if (On(Behaviour.cohesion))
        {
            force = Cohesion(entity, nearby) * entity.WeightCohesion;

            if (!AccumulateForce(entity, ref m_SteeringForce, force)) return m_SteeringForce;
        }

        if (On(Behaviour.seek))
        {
            force = Seek(entity, target) * entity.WeightSeek;

            if (!AccumulateForce(entity, ref m_SteeringForce, force)) return m_SteeringForce;
        }

        /*
        if (On(Behaviour.arrive))
        {
            force = Arrive(m_pVehicle->World()->Crosshair(), m_Deceleration) * m_dWeightArrive;

            if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce;
        }
        */
        if (On(Behaviour.wander))
        {
            force = Wander(entity) * entity.WeightWander;

            if (!AccumulateForce(entity, ref m_SteeringForce, force)) return m_SteeringForce;
        }
        /*
        if (On(Behaviour.pursuit))
        {
            assert(m_pTargetAgent1 && "pursuit target not assigned");

            force = Pursuit(m_pTargetAgent1) * m_dWeightPursuit;

            if (!AccumulateForce(m_SteeringForce, force)) return m_SteeringForce;
        }

        if (On(Behaviour.offset_pursuit))
        {
            assert(m_pTargetAgent1 && "pursuit target not assigned");
            assert(!m_vOffset.isZero() && "No offset assigned");

            force = OffsetPursuit(m_pTargetAgent1, m_vOffset);

            if (!AccumulateForce(m_vSteeringForce, force)) return m_SteeringForce;
        }

        if (On(Behaviour.interpose))
        {
            Debug.Assert(m_pTargetAgent1 && m_pTargetAgent2, "Interpose agents not assigned");

            force = Interpose(m_pTargetAgent1, m_pTargetAgent2) * m_dWeightInterpose;

            if (!AccumulateForce(m_vSteeringForce, force)) return m_vSteeringForce;
        }

        if (On(Behaviour.hide))
        {
            assert(m_pTargetAgent1 && "Hide target not assigned");

            force = Hide(m_pTargetAgent1, m_pVehicle->World()->Obstacles()) * m_dWeightHide;

            if (!AccumulateForce(m_vSteeringForce, force)) return m_SteeringForce;
        }

        if (On(Behaviour.follow_path))
        {
            force = FollowPath() * m_dWeightFollowPath;

            if (!AccumulateForce(m_vSteeringForce, force)) return m_SteeringForce;
        }
        */
        return m_SteeringForce;
    }
    //---------------------- CalculateWeightedSum ----------------------------
    //
    //  this simply sums up all the active behaviors X their weights and
    //  truncates the result to the max available steering force before
    //  returning
    //------------------------------------------------------------------------
    Vector3 CalculateWeightedSum(FlockEntity entity, List<FlockEntity> nearby, Vector3 target)
    {
        if (On(Behaviour.separation))
        {
            m_SteeringForce += Separation(entity, nearby) * entity.WeightSeparation;
        }

        if (On(Behaviour.allignment))
        {
            m_SteeringForce += Alignment(entity, nearby) * entity.WeightAlignment;
        }

        if (On(Behaviour.cohesion))
        {
            m_SteeringForce += Cohesion(entity, nearby) * entity.WeightCohesion;
        }

        if (On(Behaviour.wander))
        {
            m_SteeringForce += Wander(entity) * entity.WeightWander;
        }

        if (On(Behaviour.seek))
        {
            m_SteeringForce += Seek(entity, target) * entity.WeightSeek;
        }

        if (On(Behaviour.flee))
        {
            m_SteeringForce += Flee(entity, target) * entity.WeightFlee;
        }
        /*
        if (On(Behaviour.arrive))
        {
            m_vSteeringForce += Arrive(m_pVehicle->World()->Crosshair(), m_Deceleration) * m_dWeightArrive;
        }

        if (On(Behaviour.pursuit))
        {
            Debug.Assert(m_pTargetAgent1, "pursuit target not assigned");

            m_vSteeringForce += Pursuit(m_pTargetAgent1) * m_dWeightPursuit;
        }

        if (On(offset_pursuit))
        {
            Debug.Assert(m_pTargetAgent1, "pursuit target not assigned");
            Debug.Assert(!m_vOffset.isZero(), "No offset assigned");

            m_vSteeringForce += OffsetPursuit(m_pTargetAgent1, m_vOffset) * m_dWeightOffsetPursuit;
        }
        */
        Vector3.ClampMagnitude(m_SteeringForce, entity.m_MaxForce);

        return m_SteeringForce;
    }
    //-------------------------------- Cohesion ------------------------------
    //
    //  returns a steering force that attempts to move the agent towards the
    //  center of mass of the agents in its immediate area
    //------------------------------------------------------------------------
    Vector3 Cohesion(FlockEntity entity, List<FlockEntity> nearby)
    {
        //first find the center of mass of all the agents
        Vector3 CenterOfMass = Vector3.zero;
        Vector3 SteeringForce = Vector3.zero;

        int NeighborCount = 0;

        //iterate through the neighbors and sum up all the position vectors
        for (int a = 0; a < nearby.Count; ++a)
        {
            if (nearby[a].Tagged)
            {
                CenterOfMass += nearby[a].transform.position;
                ++NeighborCount;
            }
        }

        if (NeighborCount > 0)
        {
            //the center of mass is the average of the sum of positions
            CenterOfMass /= (float)NeighborCount;

            //now seek towards that position
            SteeringForce = Seek(entity, CenterOfMass);
        }

        //the magnitude of cohesion is usually much larger than separation or
        //allignment so it usually helps to normalize it.
        return SteeringForce.normalized;
    }
    Vector3 Flee(FlockEntity entity, Vector3 TargetPos)
    {
        //only flee if the target is within 'panic distance'. Work in distance
        //squared space.
        /* const double PanicDistanceSq = 100.0f * 100.0;
         if (Vec2DDistanceSq(m_pVehicle->Pos(), target) > PanicDistanceSq)
         {
           return Vector2D(0,0);
         }
         */

        Vector3 DesiredVelocity = Vector3.Normalize(entity.Position - TargetPos) * entity.m_MaxSpeed;
        return (DesiredVelocity - entity.m_Velocity);
    }
示例#22
0
 public SwimmingState(FSM <CheepCheep.States> fsm, CheepCheep fish, FlockEntity flockEntity)
 {
     _fsm         = fsm;
     _fish        = fish;
     _flockEntity = flockEntity;
 }
 Vector3 Seek(FlockEntity entity, Vector3 TargetPos)
 {
     Vector3 DesiredVelocity = Vector3.Normalize(TargetPos - entity.Position) * entity.m_MaxSpeed;
     return (DesiredVelocity - entity.m_Velocity);
 }
    Vector3 Wander(FlockEntity entity)
    {
        //this behavior is dependent on the update rate, so this line must
        //be included when using time independent framerate.
        float JitterThisTimeSlice = m_WanderJitter * Time.deltaTime;

        //first, add a small random vector to the target's position
        m_WanderTarget += Random.insideUnitSphere * JitterThisTimeSlice;

        //reproject this new vector back on to a unit circle
        m_WanderTarget.Normalize();

        //increase the length of the vector to the same as the radius
        //of the wander circle
        m_WanderTarget *= m_WanderRadius;

        //move the target into a position WanderDist in front of the agent
        Vector3 target = m_WanderTarget + new Vector3(0,0,m_WanderDistance);

        target = entity.transform.rotation * target;

        //and steer towards it
        return target;
    }
    //---------------------------- Separation --------------------------------
    //
    // this calculates a force repelling from the other neighbors
    //------------------------------------------------------------------------
    Vector3 Separation(FlockEntity entity, List<FlockEntity> nearby)
    {
        Vector3 SteeringForce = Vector3.zero;

        for (int a = 0; a < nearby.Count; ++a)
        {
            //make sure this agent isn't included in the calculations and that
            //the agent being examined is close enough. ***also make sure it doesn't
            //include the evade target ***
            if (nearby[a].Tagged)
            {
                Vector3 ToAgent = entity.transform.position - nearby[a].transform.position;

                if (ToAgent.sqrMagnitude < 0.001f)
                {
                    // if next to randomly move away from
                    SteeringForce += Random.insideUnitSphere;
                }
                else
                {
                    //scale the force inversely proportional to the agents distance
                    //from its neighbor.
                    SteeringForce += Vector3.Normalize(ToAgent) / ToAgent.magnitude;
                }
            }
        }

        return SteeringForce;
    }
示例#26
0
 private void Awake()
 {
     flock = GetComponent <FlockEntity>();
 }
 // Start is called before the first frame update
 public override void Start()
 {
     base.Start();
     flock = GetComponent <FlockEntity>();
 }