Beispiel #1
0
    public void MoveGrounded(float speed)
    {
        Vector3 targetVector = RawTargetVector(speed);

        targetAngle = Vector3.SignedAngle(Vector3.forward, targetVector.normalized, Vector3.up);
        targetSpeed = UMath.GetHorizontalMag(targetVector);

        anim.SetFloat("SignedTargetAngle", targetAngle);
        anim.SetFloat("TargetAngle", Mathf.Abs(targetAngle));
        anim.SetFloat("TargetSpeed", targetSpeed);

        // Allows Lara to smoothly take off
        if (localVelocity.sqrMagnitude == 0f && targetVector.magnitude > 0.1f)
        {
            Vector3 camForward = cam.forward;
            camForward.y = 0f;
            camForward.Normalize();

            // Finds correct forward direction for local velocity
            localVelocity = Quaternion.FromToRotation(camForward, transform.forward) * (Vector3.forward * 0.1f);
        }

        localVelocity = Vector3.Slerp(localVelocity, targetVector, Time.deltaTime * speedChangeRate);

        velocity = Quaternion.Euler(0f, cam.eulerAngles.y, 0f) * localVelocity;

        float actualSpeed = direction * UMath.GetHorizontalMag(velocity);

        anim.SetFloat("Speed", actualSpeed);
    }
Beispiel #2
0
    public override void Update(PlayerController player)
    {
        if (Time.time - timeTracker >= grabTime)
        {
            if (ledgeInfo.Type == LedgeType.Monkey || (UMath.GetHorizontalMag(player.Velocity) > 2f && HasFeetRoom()))
            {
                player.Anim.SetTrigger("DeepGrab");
            }
            if (UMath.GetHorizontalMag(player.Velocity) > 0.2f)
            {
                player.Anim.SetTrigger("Grab");
            }
            else
            {
                player.Anim.SetTrigger("StandGrab");
            }

            player.transform.position = grabPoint;

            if (ledgeInfo.Type == LedgeType.Free)
            {
                player.StateMachine.GoToState <Freeclimb>();
            }
            else if (ledgeInfo.Type == LedgeType.Monkey)
            {
                player.StateMachine.GoToState <MonkeySwing>();
            }
            else
            {
                player.StateMachine.GoToState <Climbing>();
            }
        }
    }
Beispiel #3
0
    private bool TryReachLedge(PlayerController player, float zVel, ref float yVel, bool allowClearingBoost = true)
    {
        // Doing standing jump, allow player to grab if close
        if (zVel < 0.5f)
        {
            zVel = 0.5f;
        }

        // Need to check where player will be relative to ledge
        float   timeAtPeak   = yVel / player.Gravity; // v = u + at
        Vector3 relative     = ledgeInfo.Point - player.transform.position;
        float   displacement = UMath.GetHorizontalMag(relative);
        // Maximum to account for when player hits wall but keeps moving up
        float timeAtLedge = Mathf.Max(UMath.TimeAtHorizontalPoint(zVel, displacement), timeAtPeak);
        float vertPos     = UMath.PredictDisplacement(yVel, timeAtLedge, -player.Gravity);

        if (vertPos >= relative.y - 2.6f && vertPos <= relative.y - 0.8f) // Distance is great, do auto-grab
        {
            player.StateMachine.GoToState <AutoGrabbing>(ledgeInfo);
            return(true);
        }
        else if (allowClearingBoost && vertPos < relative.y && vertPos > relative.y - 0.8f) // she hits it around the hip just adjust up velocity to clear it
        {
            float   time;
            Vector3 adjustedVel = UMath.VelocityToReachPoint(player.transform.position,
                                                             ledgeInfo.Point, zVel, player.Gravity, out time);
            yVel = adjustedVel.y;
        }

        return(false);
    }
Beispiel #4
0
 public void RotateToCamera()
 {
     if (UMath.GetHorizontalMag(velocity) > 0.1f)
     {
         Quaternion target = Quaternion.LookRotation(cam.transform.forward, Vector3.up);
         target             = Quaternion.Euler(0f, target.eulerAngles.y, 0f);
         transform.rotation = target;
     }
 }
Beispiel #5
0
    public override void Update(PlayerController player)
    {
        if (player.Grounded)
        {
            Debug.Log("Unfortunately grounded my love");
            player.StateMachine.GoToState <Locomotion>();
            return;
        }

        if (Time.time - timeTracker >= grabTime)
        {
            // adjust to align with moving ledge
            if (ledgeInfo.Collider != null)
            {
                Vector3 change = ledgeInfo.Collider.transform.position - initialColliderPos;
                grabPoint += change;
            }

            if (ledgeInfo.Type != LedgeType.HorPole)
            {
                if (UMath.GetHorizontalMag(player.Velocity) > 2f && HasFeetRoom())
                {
                    player.Anim.SetTrigger("DeepGrab");
                }
                if (UMath.GetHorizontalMag(player.Velocity) > 0.2f)
                {
                    player.Anim.SetTrigger("Grab");
                }
                else
                {
                    player.Anim.SetTrigger("StandGrab");
                }
            }

            player.transform.position = grabPoint;
            player.transform.rotation = targetRot;

            if (ledgeInfo.Type == LedgeType.Free)
            {
                player.StateMachine.GoToState <Freeclimb>();
            }
            else if (ledgeInfo.Type == LedgeType.Monkey)
            {
                player.StateMachine.GoToState <MonkeySwing>();
            }
            else
            {
                player.StateMachine.GoToState <Climbing>();
            }
        }
    }
Beispiel #6
0
    // This method is necessary as Lara must run backwards 50% of the time
    public void RotateToVelocityStrafe(float smoothing = 8f)
    {
        if (UMath.GetHorizontalMag(velocity) < 0.1f)
        {
            return;
        }

        float theAngle = Mathf.Atan2(velocity.x, velocity.z) * Mathf.Rad2Deg;

        if (targetAngle < -50f || targetAngle > 140f)
        {
            if (direction != -1)
            {
                adjustRotCombat = true;
            }
            direction = -1;
        }
        else if (targetAngle > -40f && targetAngle < 130f)
        {
            if (direction != 1)
            {
                adjustRotCombat = true;
            }
            direction = 1;
        }

        if (direction == -1)
        {
            theAngle += 180f;
        }

        Quaternion target = Quaternion.Euler(0.0f, theAngle, 0.0f);

        if (!adjustRotCombat)
        {
            transform.rotation = target;
        }
        else
        {
            if (Mathf.Abs(Quaternion.Angle(target, transform.rotation)) > 10f)
            {
                transform.rotation = Quaternion.Slerp(transform.rotation, target, smoothing * Time.deltaTime);
            }
            else
            {
                adjustRotCombat = false;
            }
        }
    }
Beispiel #7
0
    public void RotateToVelocityGround(float smoothing = 0f)
    {
        direction = 1;

        if (UMath.GetHorizontalMag(velocity) < 0.1f)
        {
            return;
        }

        Quaternion target = Quaternion.Euler(0.0f, Mathf.Atan2(velocity.x, velocity.z) * Mathf.Rad2Deg, 0.0f);

        if (smoothing == 0f)
        {
            transform.rotation = target;
        }
        else
        {
            transform.rotation = Quaternion.Slerp(transform.rotation, target, smoothing * Time.deltaTime);
        }
    }
Beispiel #8
0
    public override void Update(PlayerController player)
    {
        // Handle Lara screaming
        if (player.VerticalSpeed <= -player.DeathVelocity && !hasScreamed)
        {
            player.SFX.PlayScreamSound();
            hasScreamed = true;
        }

        AnimatorStateInfo animState = player.Anim.GetCurrentAnimatorStateInfo(0);

        float targetSpeed = UMath.GetHorizontalMag(player.RawTargetVector());

        player.Anim.SetFloat("YSpeed", player.VerticalSpeed);
        player.Anim.SetFloat("TargetSpeed", targetSpeed);  // Useful for transitioning to other movements

        if (player.Grounded)
        {
            // Causes recalculation of local velocity
            player.Velocity = player.Velocity;

            // Apply damage if necessary
            if (player.VelocityLastFrame.y < -player.DamageVelocity)
            {
                int healthToLose = (int)((Mathf.Abs(player.VelocityLastFrame.y) - player.DamageVelocity) * 100f / (player.DeathVelocity - player.DamageVelocity));
                player.Stats.Health -= healthToLose;

                // Stops any screaming currently happening
                player.GetComponent <AudioSource>().Stop();

                if (player.Stats.Health == 0)
                {
                    player.SFX.PlayHitGroundSound();
                    return;  // Player transitioning into death so ignore rest
                }
            }

            // Smooth transition to slope sliding
            if (player.Ground.Tag == "Slope")
            {
                player.StateMachine.GoToState <Sliding>();
                return;
            }

            // Determine proper land animation trigger
            string landType = animState.IsName("Dive") ? "DiveLand"
                : (player.VelocityLastFrame.y > -player.DamageVelocity ? "Land" : "HardLand");

            player.Anim.SetTrigger(landType);

            // Stops player moving forward on landing
            if (targetSpeed < 0.1f)
            {
                player.ImpulseVelocity(Vector3.down * player.Gravity);
            }

            player.StateMachine.GoToState <Locomotion>();

            return;
        }
        else if (!player.Anim.GetBool("isDive"))  // Other actions that be performed while not diving
        {
            if (Input.GetKeyDown(player.Inputf.action) && !player.UpperStateMachine.IsInState <UpperCombat>())
            {
                player.StateMachine.GoToState <Grabbing>();
            }
            else if (Input.GetKey(player.Inputf.drawWeapon) || Input.GetAxisRaw("CombatTrigger") > 0.1f)
            {
                if (player.VerticalSpeed > -player.DamageVelocity)
                {
                    player.UpperStateMachine.GoToState <UpperCombat>();
                }
            }
        }
    }
Beispiel #9
0
    public override void Update(PlayerController player)
    {
        AnimatorStateInfo      animState = player.Anim.GetCurrentAnimatorStateInfo(0);
        AnimatorTransitionInfo transInfo = player.Anim.GetAnimatorTransitionInfo(0);

        // Used to determine if forward or up stand jump
        float targetSpeed = UMath.GetHorizontalMag(player.RawTargetVector());

        player.Anim.SetFloat("TargetSpeed", targetSpeed);

        bool isDive = player.Anim.GetBool("isDive");

        if (!player.AutoLedgeTarget && Input.GetKey(player.Inputf.action) && !isDive)
        {
            isGrabbing = true;
        }

        // Allows player to smoothly turn round during stand jump
        if ((animState.IsName("Still_Compress_Forward") || animState.IsName("Compress")) && !noRotate && !hasJumped)
        {
            player.MoveGrounded(1f);
            player.RotateToVelocityGround();
        }

        if (Input.GetKey(player.Inputf.crouch) && !hasJumped)
        {
            player.Anim.SetBool("isDive", true);
            isDive = true;
        }

        bool isRunJump   = animState.IsName("RunJump") || animState.IsName("RunJumpM") || animState.IsName("Dive");
        bool isStandJump = animState.IsName("StandJump") || transInfo.IsName("Still_Compress_Forward -> StandJump");
        bool isJumpUp    = animState.IsName("JumpUp");

        if ((isRunJump || isStandJump || isJumpUp) && !hasJumped)
        {
            player.UseRootMotion = false;

            float zVel = isRunJump ? player.RunJumpVel
                : isStandJump ? player.StandJumpVel
                : 0.1f;
            float yVel = player.JumpYVel;

            // Snaps forward standing jumps to right direction (more responsive)
            if (isStandJump && !noRotate)
            {
                Vector3 targetJumpDir = player.RawTargetVector(1f, true);

                if (targetJumpDir.sqrMagnitude != 0f)  // Stops Lara snapping to (0,0,1)
                {
                    Quaternion rotationTarget = Quaternion.LookRotation(targetJumpDir, Vector3.up);
                    player.transform.rotation = rotationTarget;
                }
            }

            // Checks for ledges
            if (player.AutoLedgeTarget && !isDive)
            {
                Vector3 autoGrabCastStart = player.transform.position + Vector3.down * 2.5f;
                float   autoGrabMaxHeight = 2.5f + player.JumpHeight + player.GrabUpOffset;

                ledgesDetected = ledgeDetector.FindLedgeJump(autoGrabCastStart, player.transform.forward, 6.2f, autoGrabMaxHeight, out ledgeInfo, player);

                if (ledgesDetected && TryReachLedge(player, zVel, ref yVel))
                {
                    return;  // Can reach ledge - ignore code left in this state
                }
                else
                {
                    // Check for monkeys and poles
                    Vector3 start = player.transform.position + Vector3.up * player.CharControl.height;
                    Vector3 dir   = isJumpUp ? Vector3.up : player.transform.forward + Vector3.up;
                    ledgesDetected = ledgeDetector.FindAboveHead(start, dir, 4f, out ledgeInfo);

                    if (ledgesDetected)
                    {
                        player.StateMachine.GoToState <AutoGrabbing>(ledgeInfo);
                        return;
                    }
                }
            }

            player.ImpulseVelocity(player.transform.forward * zVel + Vector3.up * yVel);

            hasJumped = true;
        }
        else if (hasJumped)
        {
            if (isGrabbing)
            {
                player.StateMachine.GoToState <Grabbing>();
                return;
            }
            else
            {
                player.StateMachine.GoToState <InAir>();
                return;
            }
        }
    }
Beispiel #10
0
    public override void Update(PlayerController player)
    {
        // Handle Lara screaming
        if (player.VerticalSpeed <= -player.DeathVelocity && !screamed)
        {
            player.SFX.PlayScreamSound();
            screamed = true;
        }

        AnimatorStateInfo animState = player.Anim.GetCurrentAnimatorStateInfo(0);

        player.Anim.SetFloat("YSpeed", player.VerticalSpeed);

        float targetSpeed = UMath.GetHorizontalMag(player.RawTargetVector());

        player.Anim.SetFloat("TargetSpeed", targetSpeed);

        if (player.Grounded)
        {
            // Apply damage if necessary
            if (player.VelocityLastFrame.y < -player.DamageVelocity)
            {
                int healthToLose = (int)((Mathf.Abs(player.VelocityLastFrame.y) - player.DamageVelocity) * 100f / (player.DeathVelocity - player.DamageVelocity));
                player.Stats.Health -= healthToLose;

                player.GetComponent <AudioSource>().Stop();

                if (player.Stats.Health == 0)
                {
                    player.SFX.PlayHitGroundSound();
                }
            }

            // Smooth transition to slope sliding
            if (player.Ground.Tag == "Slope")
            {
                player.StateMachine.GoToState <Sliding>();
                return;
            }

            // Determine proper land animation trigger
            string landType = animState.IsName("Dive") ? "DiveLand"
                : (player.VelocityLastFrame.y > -player.DamageVelocity ? "Land" : "HardLand");

            player.Anim.SetTrigger(landType);

            // Stops player moving forward on landing
            if (player.RawTargetVector().magnitude < 0.1f)
            {
                player.ImpulseVelocity(Vector3.down * player.Gravity);
            }

            // Don't want player to come out of death state
            if (player.Stats.IsAlive())
            {
                player.StateMachine.GoToState <Locomotion>();
            }

            return;
        }
        else if (!player.Anim.GetBool("isDive"))
        {
            if (Input.GetKeyDown(player.Inputf.action) && !player.UpperStateMachine.IsInState <UpperCombat>())
            {
                player.StateMachine.GoToState <Grabbing>();
            }
            else if (Input.GetKey(player.Inputf.drawWeapon) || Input.GetAxisRaw("CombatTrigger") > 0.1f)
            {
                if (player.VerticalSpeed > -player.DamageVelocity)
                {
                    player.UpperStateMachine.GoToState <UpperCombat>();
                }
            }
        }
    }