// Update is called once per frame
    void LateUpdate()
    {
        if (PlayerStates.Singleton.IsDead)
        {
            die.Execute(animator);
            return;
        }

        // Pause Game
        if (GameInputManager.GetKeyUp("Pause"))
        {
            PlayerStates.Singleton.TooglePause();
        }

        if (PlayerStates.Singleton.IsPaused)
        {
            return;
        }

        PlayerStates.Singleton.Position = transform.position;

        PlayerStates.Singleton.IsWalking  = GameInputManager.GetKey("Walk");
        PlayerStates.Singleton.IsGrounded = characterController.isGrounded;

        if (PlayerStates.Singleton.IsGrounded)
        {
            // Move
            float verticalAxis = 0f;
            if (GameInputManager.GetKey("Forward"))
            {
                verticalAxis = 1f;
            }
            else if (GameInputManager.GetKey("Backward"))
            {
                verticalAxis = -1f;
            }

            if (GameInputManager.GetKey("Sprint") && PlayerStates.Singleton.Stamina > 0f)
            {
                PlayerStates.Singleton.IsSprinting = true;
            }
            else
            {
                PlayerStates.Singleton.IsSprinting = false;
            }

            moveDirection = new Vector3(0, 0, verticalAxis);
            moveDirection = transform.TransformDirection(moveDirection);

            if (verticalAxis > 0 && PlayerStates.Singleton.IsWalking)
            {
                moveDirection *= PlayerStates.Singleton.WalkingSpeed;
                walk.Execute(animator);
            }
            else if (verticalAxis < 0)
            {
                PlayerStates.Singleton.IsWalkingBackward = true;
                moveDirection *= PlayerStates.Singleton.WalkingBackSpeed;
                walkBack.Execute(animator);
            }
            else if (verticalAxis > 0)
            {
                PlayerStates.Singleton.IsRunning         = true;
                PlayerStates.Singleton.IsWalkingBackward = false;
                moveDirection *= PlayerStates.Singleton.RunningSpeed + (PlayerStates.Singleton.IsSprinting ? PlayerStates.Singleton.SprintSpeedBoost : 0);
                run.Execute(animator);
            }
            else
            {
                PlayerStates.Singleton.IsWalkingBackward = false;
                PlayerStates.Singleton.IsRunning         = false;
                idle.Execute(animator);
            }

            // Jumps
            if (GameInputManager.GetKey("Jump") &&
                !PlayerStates.Singleton.IsJumping &&
                PlayerStates.Singleton.IsWalking &&
                PlayerStates.Singleton.Stamina >= PlayerStates.Singleton.StaminaNeededForJump &&
                !PlayerStates.Singleton.IsWalkingBackward)
            {
                PlayerStates.Singleton.IsJumping = true;
                Invoke("SetIsJumpingToFalse", 2.8f * Time.timeScale);
                PlayerStates.Singleton.Stamina -= PlayerStates.Singleton.StaminaNeededForJump;
                moveDirection.y = PlayerStates.Singleton.JumpHeight;
                moveDirection.z = PlayerStates.Singleton.JumpDistance;
                moveDirection   = transform.TransformDirection(moveDirection);
                jump.Execute(animator);
            }
            else if (GameInputManager.GetKey("Jump") && PlayerStates.Singleton.IsWalkingBackward)
            {
                moveDirection.y = PlayerStates.Singleton.BackJumpSpeed;
                moveDirection.z = -PlayerStates.Singleton.BackJumpDistance;
                moveDirection   = transform.TransformDirection(moveDirection);
                jumpBack.Execute(animator);
            }
        }

        // Gravity
        moveDirection.y -= PlayerStates.Singleton.Gravity * Time.deltaTime;
        characterController.Move(moveDirection * Time.deltaTime);


        // Rotation
        float horizontalAxis = 0;

        if (GameInputManager.GetKey("Left"))
        {
            horizontalAxis = -1f;
        }
        else if (GameInputManager.GetKey("Right"))
        {
            horizontalAxis = 1f;
        }

        transform.Rotate(0, horizontalAxis * PlayerStates.Singleton.RotationSpeed, 0);
        transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.FromToRotation(transform.up, GetHitNormal()) * transform.rotation, 5 * Time.deltaTime);
    }