public static Vector3 Evade(SteeringActor actor, SteeringActor pursuer)
    {
        SteeringBehaviours.Forces attributes = actor.GetAttributes().Forces;

        Vector3 toPursuer = pursuer.GetPosition() - actor.GetPosition();

        float lookAhreadTime = toPursuer.magnitude / (attributes.MaxSpeed + pursuer.GetVelocity().magnitude);
        return Flee(actor, pursuer.GetPosition() + (Vector3)pursuer.GetVelocity() * lookAhreadTime);
    }
    public static Vector3 Pursuit(SteeringActor actor, SteeringActor evader)
    {
        SteeringBehaviours.Forces attributes = actor.GetAttributes().Forces;
        Vector3 toEvader = evader.GetPosition() - actor.GetPosition();

        Vector3 thisHeading = actor.GetVelocity();
        thisHeading.Normalize();

        Vector3 evaderHeading = evader.GetVelocity();
        evaderHeading.Normalize();
        float relativeHeading = Vector3.Dot(thisHeading, evaderHeading);

        float tresholdAngleAcos = Mathf.Acos(attributes.PursuitThresholdAngle);
        if (Vector3.Dot(toEvader, thisHeading) > 0 && (relativeHeading < -tresholdAngleAcos))
        {
            return Seek(actor, evader.GetPosition());
        }

        // the look ahead time is proportional to the distance between the evader
        // and the pursuer; and is inversely proportional to the sum of the agents velocities
        float lookAheadTime = toEvader.magnitude / (attributes.MaxSpeed + evader.GetVelocity().magnitude);

        // Now seek to the predicted future position of the evader
        return Seek(actor, evader.GetPosition() + (Vector3) evader.GetVelocity() * lookAheadTime);
    }
    public static Vector3 Arrive(SteeringActor actor, Vector3 targetPos, SteeringBehaviours.Deceleration deceleration)
    {
        SteeringBehaviours.Forces attributes = actor.GetAttributes().Forces;

        Vector3 toTarget = targetPos - actor.GetPosition();

        float dist = toTarget.magnitude;
        if (dist <= 0)
        {
            return new Vector3();
        }

        float decelerationTweaker = 0.3f;
        float speed = dist / ((float)deceleration * decelerationTweaker);

        speed = Mathf.Min(speed, attributes.MaxSpeed);

        Vector3 desiredVelocity = toTarget * speed / dist;

        return desiredVelocity;// - GetVelocity();
    }
    public static Vector3 Flee(SteeringActor actor, Vector3 targetPos)
    {
        SteeringBehaviours.Forces attributes = actor.GetAttributes().Forces;

        Vector3 fromTarget = actor.GetPosition() - targetPos;
        fromTarget.Normalize();
        Vector3 desiredVelocity = fromTarget * attributes.MaxSpeed;
        return desiredVelocity;// - GetVelocity();
    }
    public static Vector3 Seek(SteeringActor actor, Vector3 targetPos)
    {
        SteeringBehaviours.Forces attributes = actor.GetAttributes().Forces;

        Vector3 toTarget = (targetPos - actor.GetPosition());
        toTarget.Normalize();
        Vector3 desiredVelocity = toTarget * attributes.MaxSpeed;
        return desiredVelocity;// - GetVelocity();
    }
 public static bool IsTargetFront(SteeringActor actor, SteeringActor target)
 {
     Vector3 toTarget = target.GetPosition() - actor.GetPosition();
     toTarget.Normalize();
     return Vector3.Dot(actor.GetForward(), toTarget) > 0;
 }