bool GetStepInfo(out StepFound step, ContactPoint contact, ContactPoint ground, bool isGrounded)
    {
        step = null;
        RaycastHit stepTest;

        Vector3 stepOverbite = Vector3.ProjectOnPlane(-contact.normal.normalized, transform.up).normalized *
                               stepOverbiteMagnitude;

        // Start the raycast position directly above the contact point with the step
        Debug.DrawRay(contact.point, transform.up * (maxStepHeight * 0.8f), Color.blue, 10);
        Vector3 raycastStartPos = contact.point + transform.up * (maxStepHeight * 0.8f);

        // Move the raycast inwards towards the stair (we will be raycasting down at the stair)
        Debug.DrawRay(raycastStartPos, stepOverbite, Color.red, 10);
        raycastStartPos += stepOverbite;
        Vector3 direction = -transform.up;

        Debug.DrawRay(raycastStartPos, direction * maxStepHeight, Color.green, 10);
        bool stepFound = contact.otherCollider.Raycast(
            new Ray(raycastStartPos, direction),
            out stepTest,
            maxStepHeight
            );

        if (stepFound)
        {
            bool stepIsGround = Vector3.Dot(stepTest.normal, transform.up) > isGroundThreshold;
            if (!stepIsGround)
            {
                return(false);
            }

            Vector3 groundPointOrBottomOfPlayer = isGrounded ? ground.point : bottomOfPlayer;
            float   stepHeight = Vector3.Dot(transform.up, stepTest.point - groundPointOrBottomOfPlayer);

            Vector3 stepOffset = stepOverbite + transform.up * (stepHeight + 0.02f);
            Debug.DrawRay(contact.point, stepOffset, Color.black, 10);
            step = new StepFound(contact, stepOffset);
            debug.Log($"Step: {contact}\n{stepOffset:F3}\nstepHeight:{stepHeight}");
        }

        return(stepFound);
    }
    void FixedUpdate()
    {
        UpdateGroundedState();

        if (stopped || grounded.standingOnHeldObject)
        {
            allContactThisFrame.Clear();
            return;
        }

        UpdateJumping();

        Vector3 desiredVelocity = thisRigidbody.velocity;

        if (grounded.isGrounded)
        {
            desiredVelocity = CalculateGroundMovement(grounded.contact);
        }
        else
        {
            desiredVelocity = CalculateAirMovement();
        }

        // Prevent player from floating around on cubes they're holding...
        if (grounded.standingOnHeldObject)
        {
            desiredVelocity += 4 * Physics.gravity * Time.fixedDeltaTime;
        }

        float movingBackward = Vector2.Dot(
            new Vector2(desiredVelocity.x, desiredVelocity.z),
            new Vector2(transform.forward.x, transform.forward.z)
            );

        if (movingBackward < -0.5f)
        {
            float slowdownAmount = Mathf.InverseLerp(-.5f, -1, movingBackward);
            desiredVelocity.x *= Mathf.Lerp(1, backwardsSpeed, slowdownAmount);
            desiredVelocity.z *= Mathf.Lerp(1, backwardsSpeed, slowdownAmount);
        }

        if (!input.LeftStickHeld && !input.SpaceHeld && grounded.ground != null &&
            grounded.ground.CompareTag("Staircase"))
        {
            thisRigidbody.constraints = RigidbodyConstraints.FreezeAll;
        }
        else
        {
            thisRigidbody.constraints = RigidbodyConstraints.FreezeRotation;
        }

        StepFound stepFound = DetectStep(desiredVelocity, grounded.contact, grounded.isGrounded);

        if (stepFound != null)
        {
            transform.Translate(stepFound.stepOffset, Space.World);
            Player.instance.cameraFollow.SetLerpSpeed(CameraFollow.desiredLerpSpeed);
            if (Vector3.Dot(transform.up, stepFound.stepOffset) > 0)
            {
                OnStaircaseStepUp?.Invoke();
            }
        }

        thisRigidbody.useGravity = !grounded.isGrounded;

        thisRigidbody.velocity = desiredVelocity;

        // Apply wind resistance
        Vector3 projectedVertVelocity = ProjectedVerticalVelocity();

        if (!grounded.isGrounded && Vector3.Dot(Physics.gravity.normalized, projectedVertVelocity.normalized) > 0)
        {
            thisRigidbody.AddForce(
                transform.up * projectedVertVelocity.magnitude * thisRigidbody.mass * windResistanceMultiplier
                );
        }

        allContactThisFrame.Clear();
    }