protected void FixedUpdate()
    {
        if (currentIntroState.state != IntroState.Player_Ready || done)
        {
            return;
        }

        if (playerRb.position.x >= 6.75f)
        {
            portalGI.PlayAudioZap();

            NextState();
            playerRb.isKinematic = true;
            player.gameObject.SetActive(false);

            return;
        }

        // check for landing
        if (Mathf.Abs(playerRb.velocity.y) < 0.1f)
        {
            if (isJumping)
            {
                float distance = 0.4f;
                if (Physics.Raycast(playerRb.position + new Vector3(0, 0.1f, 0), Vector3.down, out _, distance))
                {
                    isJumping = false;
                    playerFrontRendererTransform.localRotation = Quaternion.Euler(0f, 0f, 0f);
                }
            }
        }
        else
        {
            isJumping = true;
        }

        // horizontal movement
        if (horizontalInputSinceFixedUpdate != 0f)
        {
            playerRb.AddForce(Vector3.right * horizontalInputSinceFixedUpdate * playerAccel, ForceMode.VelocityChange);
        }
        // ensure max speed
        Vector3 velocity = playerRb.velocity;

        velocity.x        = Mathf.Clamp(velocity.x, -playerMaxSpeed, playerMaxSpeed);
        playerRb.velocity = velocity;

        // vertical movement
        if (shouldJump && !isJumping)
        {
            isJumping = true;
            playerRb.AddForce(Vector3.up * jumpImpulse, ForceMode.Impulse);

            player.PlayAudioJump();
        }

        // reset inputs
        horizontalInputSinceFixedUpdate = 0f;
        shouldJump = false;
    }
    protected void FixedUpdate()
    {
        // check for landing
        if (Mathf.Abs(playerRb.velocity.y) < 0.1f)
        {
            if (isJumping)
            {
                float distance = 0.4f;
                if (Physics.Raycast(playerRb.position + new Vector3(0, 0.1f, 0), Vector3.down, out _, distance))
                {
                    isJumping = false;
                    playerFrontRendererTransform.localRotation = Quaternion.Euler(0f, 0f, 0f);
                }
            }
        }
        else
        {
            isJumping = true;
        }

        // horizontal movement
        if (horizontalInputSinceFixedUpdate != 0f)
        {
            playerRb.AddForce(Vector3.right * horizontalInputSinceFixedUpdate * playerAccel, ForceMode.VelocityChange);
        }
        // ensure max speed
        Vector3 velocity = playerRb.velocity;

        velocity.x        = Mathf.Clamp(velocity.x, -playerMaxSpeed, playerMaxSpeed);
        playerRb.velocity = velocity;

        // vertical movement
        if (shouldJump && !isJumping)
        {
            isJumping = true;
            playerRb.AddForce(Vector3.up * jumpImpulse, ForceMode.Impulse);

            playerGameItem.PlayAudioJump();
        }

        // reset inputs
        horizontalInputSinceFixedUpdate = 0f;
        shouldJump = false;

        // position changes from triggered events
        foreach (KeyValuePair <Rigidbody, Vector3> keyValuePair in positionChanges)
        {
            if (keyValuePair.Key == null)
            {
                continue;
            }
            keyValuePair.Key.position += keyValuePair.Value;
        }
        positionChanges.Clear();
    }