public override void UpdateWander(Follower follower)
    {
        KinematicInput  followerInput = BuildInput(follower);
        KinematicOutput output        = PerformWander(followerInput);

        ApplyOutput(follower, output);
    }
    private KinematicInput BuildInput(Follower follower)
    {
        Vector2 targetPosition = follower.hasFollowerScript
            ? follower.followerTarget.position
            : Vector2.zero;

        if (!follower.hasFollowerScript && follower.target != null)
        {
            targetPosition = follower.target.transform.position.XZ();
        }

        Vector2 targetVelocity = follower.hasFollowerScript
            ? follower.followerTarget.velocity
            : Vector2.zero;


        KinematicInput followerInput = new KinematicInput {
            position       = follower.position,
            velocity       = follower.velocity,
            orientation    = follower.orientation,
            maxVelocity    = follower.maxVelocity,
            maxRotation    = follower.maxRotation,
            targetPosition = targetPosition,
            targetVelocity = targetVelocity
        };

        return(followerInput);
    }
    public override void UpdateTargetPursue(Follower follower)
    {
        KinematicInput  followerInput = BuildInput(follower);
        KinematicOutput output        = PerformPursue(followerInput);

        ApplyOutput(follower, output);
    }
    private KinematicOutput PerformFlee(KinematicInput input)
    {
        Vector2 velocity    = input.position - input.targetPosition;
        float   orientation = GetNewOrientation(input.orientation, velocity);

        return(new KinematicOutput {
            velocity = velocity, orientation = orientation
        });
    }
    private KinematicOutput PerformWander(KinematicInput input)
    {
        Vector2 velocity    = new Vector2(input.maxVelocity, input.maxVelocity) * OrientationAsVector(input.orientation);
        float   orientation = input.orientation;
        float   rotation    = RandomBinomial() * input.maxRotation;

        return(new KinematicOutput {
            velocity = velocity, orientation = orientation, rotation = rotation
        });
    }
Ejemplo n.º 6
0
    // Start is called before the first frame update
    void Start()
    {
        rend          = GetComponent <Renderer>();
        colorNoDamage = rend.material.color;

        currentMajorDamageTimer  = 0.0f;
        currentMediumDamageTimer = 0.0f;

        IK = GetComponent <KinematicInput>();
        healthSlider.value = health;
    }
    private KinematicOutput PerformPursue(KinematicInput input)
    {
        Vector2 direction = input.targetPosition - input.position;
        float   distance  = direction.magnitude;
        float   speed     = input.velocity.magnitude;

        float predictionTime = speed <= distance / MAX_PREDICTION
            ? MAX_PREDICTION
            : distance / speed;

        input.targetPosition += input.targetVelocity * predictionTime;
        return(PerformSeek(input));
    }
    private KinematicOutput PerformArrive(KinematicInput input)
    {
        Vector2 velocity = input.targetPosition - input.position;

        if (velocity.sqrMagnitude < SATISFACTION_RADIUS * SATISFACTION_RADIUS)
        {
            return(new KinematicOutput {
                orientation = input.orientation
            });
        }

        velocity /= TIME_TO_TARGET;
        float orientation = GetNewOrientation(input.orientation, velocity);

        return(new KinematicOutput {
            velocity = velocity, orientation = orientation
        });
    }
    public override void UpdateTargetHunt(Follower follower, bool fleeing)
    {
        KinematicInput followerInput = BuildInput(follower);

        KinematicOutput output = new KinematicOutput();

        if (fleeing)
        {
            // C.1
            if (Vector2.Distance(followerInput.position, followerInput.targetPosition) < SLOW_RADIUS)
            {
                // Debug.Log("C1");
                output             = PerformFlee(followerInput);
                output.orientation = followerInput.orientation;
                output.rotation    = 0f;
            }
            else
            {
                // C.2
                // Debug.Log("C2");

                Vector2 targetRotationVect = followerInput.targetPosition - followerInput.position;
                float   targetOrientation  = Mathf.Atan2(targetRotationVect.y, targetRotationVect.x) + Mathf.PI;

                const float ANGLE_TOLERANCE = 10f;
                if (AngleDifferenceNegligible(followerInput.orientation, targetOrientation, ANGLE_TOLERANCE))
                {
                    output = PerformFlee(followerInput);
                }
                else
                {
                    output.velocity    = Vector2.zero;
                    output.orientation = Mathf.LerpAngle(followerInput.orientation * Mathf.Rad2Deg,
                                                         targetOrientation * Mathf.Rad2Deg, Time.deltaTime * 5f);
                    output.orientation *= Mathf.Deg2Rad;
                    output.rotation     = 0f;
                }
            }
        }
        else if (followerInput.velocity.magnitude < SLOW_SPEED)
        {
            // A.1
            if (Vector2.Distance(followerInput.position, followerInput.targetPosition) < SLOW_RADIUS)
            {
                // Debug.Log("A1");
                output             = PerformArrive(followerInput);
                output.orientation = followerInput.orientation;
                output.rotation    = 0f;
            }
            else
            {
                // A.2
                // Debug.Log("A2");

                Vector2 targetRotationVect = followerInput.targetPosition - followerInput.position;
                float   targetOrientation  = Mathf.Atan2(targetRotationVect.y, targetRotationVect.x);

                const float ANGLE_TOLERANCE = 10f;
                if (AngleDifferenceNegligible(followerInput.orientation, targetOrientation, ANGLE_TOLERANCE))
                {
                    output = PerformArrive(followerInput);
                }
                else
                {
                    output.velocity    = Vector2.zero;
                    output.orientation = Mathf.LerpAngle(followerInput.orientation * Mathf.Rad2Deg,
                                                         targetOrientation * Mathf.Rad2Deg, Time.deltaTime * 5f);
                    output.orientation *= Mathf.Deg2Rad;
                    output.rotation     = 0f;
                }
            }
        }
        else
        {
            Vector2 targetRotationVect = followerInput.targetPosition - followerInput.position;
            float   targetOrientation  = Mathf.Atan2(targetRotationVect.y, targetRotationVect.x);

            const float ANGLE_TOLERANCE = 10f;
            // B.1
            if (AngleDifferenceNegligible(followerInput.orientation, targetOrientation, ANGLE_TOLERANCE))
            {
                // Debug.Log("B1");
                output = PerformArrive(followerInput);
            }
            else
            {
                // B.2
                // Debug.Log("B2");
                output.velocity    = Vector2.zero;
                output.orientation = Mathf.LerpAngle(followerInput.orientation * Mathf.Rad2Deg, targetOrientation,
                                                     Time.deltaTime * 5f);
                output.orientation *= Mathf.Deg2Rad;
                output.rotation     = 0f;
            }
        }

        ApplyOutput(follower, output);
    }