예제 #1
0
    public override Vector2 CalculateSteering(Vehicle agent, List <Vehicle> targets)
    {
        List <Vehicle> neighbors = new List <Vehicle>();

        foreach (Vehicle v in Vehicle.AllVehicles)
        {
            if (v != agent && (v.position - agent.position).magnitude < neighborRadius)
            {
                neighbors.Add(v);
            }
        }

        Vector2 sepSteering = Steering.Separation(agent, neighbors) * separation;
        Vector2 aliSteering = Steering.Alignment(agent, neighbors) * alignment;
        Vector2 cohSteering = Steering.Cohesion(agent, neighbors) * cohesion;
        Vector2 wanSteering = Steering.Wander(agent, 2f, 2f, 1f);

        Vector2 steering = Vector2.zero;

        if (AccumulateForce(agent, sepSteering, ref steering) && AccumulateForce(agent, cohSteering, ref steering) &&
            AccumulateForce(agent, aliSteering, ref steering) && AccumulateForce(agent, wanSteering, ref steering))
        {
            return(steering);
        }

        return(steering);
    }
    protected void Flock <T>(HashSet <T> flockMates)
        where T : Component
    {
        var vel = Vector3.zero;

        //flockmates contains this object aswell
        if (flockMates.Count > 1)
        {
            Vector3 cohesionTarget;
            var     cohesionVel  = Steering.Cohesion(gameObject, flockMates, out cohesionTarget);
            var     alignmentVel = Steering.Alignment(gameObject, flockMates) * FlockingOptions.AlignmentWeight;

            vel += alignmentVel;

            var sqrDistance = (cohesionTarget - transform.position).sqrMagnitude;

            if (sqrDistance > FlockingOptions.MaxDispersionSquared)
            {
                if (sqrDistance > FlockingOptions.MaxDispersionSquared * 2)
                {
                    vel += cohesionVel * 1.5f;
                }
                else
                {
                    vel += cohesionVel;
                }
            }
            else if (sqrDistance < FlockingOptions.MinDispersionSquared)
            {
                if (sqrDistance < FlockingOptions.MinDispersionSquared / 2)
                {
                    vel += -cohesionVel * .75f;
                }
                else
                {
                    vel += -cohesionVel * .25f;
                }
            }
        }

        vel += Steering.Wander(gameObject, ref WanderParameters) * FlockingOptions.WanderWeight;
        //vel += Steering.Cohesion(gameObject, m_FlockMates) * .5f;

        if (vel == Vector3.zero)
        {
            vel = transform.forward;
        }

        //Use velocity so that physics continues to work
        transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(vel, transform.up), 5f);
        Rigidbody.velocity = vel.normalized * BaseSpeed;
    }