Camera speed changes depending on framerate, but ONLY with controller. Mouse speed is fine...

I have unitys new input system setup to take inputs from both a mouse+keyboard and a gamepad.

If I set the games framerate to 10, the turn speed of the camera with the controller is noticeably slower, like it almost doesn’t want to move at all. However when using the mouse the speed remains the same no matter the framerate.

Both the controller, and mouse control the same code

        public void OnCamera(InputAction.CallbackContext value)
        {
            if (PauseManager.instance.paused || PlayerInfo.instance.dead || lockMovement)
            {
                v = Vector2.zero;
                return;
            }
            if (!invertMouseY)
            {
                v = value.ReadValue<Vector2>();
            }
            else
            {
                v = value.ReadValue<Vector2>();
                v = new Vector2(v.x, -v.y);
            }
        }

So my question is… why does my mouse ignore framerate (What I want) while my controller does not?
They both use the following code :

        public virtual void LookRotation(CharacterMovement movement, Transform cameraTransform, Vector2 v)
        {
            if(lockMouseLook)
            {
                return;
            }
            var yaw = v.x * lateralSensitivity;
            var pitch = v.y * verticalSensitivity;

            var yawRotation = Quaternion.Euler(0.0f, yaw, 0.0f);
            var pitchRotation = Quaternion.Euler(-pitch, 0.0f, 0.0f);

            characterTargetRotation *= yawRotation;
            cameraTargetRotation *= pitchRotation;

            if (clampPitch)
                cameraTargetRotation = ClampPitch(cameraTargetRotation);

            if (smooth)
            {
                if (movement.platformUpdatesRotation && movement.isOnPlatform && movement.platformAngularVelocity != Vector3.zero)
                {
                    characterTargetRotation *=
                        Quaternion.Euler(movement.platformAngularVelocity * Mathf.Rad2Deg * Time.deltaTime);
                }

                movement.rotation = Quaternion.Slerp(movement.rotation, characterTargetRotation,
                    smoothTime * Time.deltaTime);

                cameraTransform.localRotation = Quaternion.Slerp(cameraTransform.localRotation, cameraTargetRotation,
                    smoothTime * Time.deltaTime);
            }
            else
            {
                movement.rotation *= yawRotation;
                cameraTransform.localRotation *= pitchRotation;

                if (clampPitch)
                    cameraTransform.localRotation = ClampPitch(cameraTransform.localRotation);
            }
        }


        protected Quaternion ClampPitch(Quaternion q)
        {
            q.x /= q.w;
            q.y /= q.w;
            q.z /= q.w;
            q.w = 1.0f;

            var pitch = 2.0f * Mathf.Rad2Deg * Mathf.Atan(q.x);

            pitch = Mathf.Clamp(pitch, minPitchAngle, maxPitchAngle);

            q.x = Mathf.Tan(0.5f * Mathf.Deg2Rad * pitch);

            return q;
        }

The control types for mouse and controller input provide entirely different values.

Mouse input is delta-driven (directly correlates with immediate change in position), where the resulting value is typically the integer number of pixels moved on a per-frame basis.

Analog Stick input is persistent, polling input (by polling the current position of the stick itself), where the resulting value typically ranges from 0-1 (floating point) per direction of the current value. (The value, in turn, for each of X/Y axes ranges from -1 to 1)

What this means in this case is that mouse input should be left as-is, and is expected to (functionally) be large, sharp values when provided. Combine that with sensitivity values to taste (This is what you’re already doing).

Controller input, however, needs to be scaled based on target degrees-per-second, scaled for framerate by Time.deltaTime.

This can still be fed into a unified function (your “LookRotation()” function) by pre-computing the delta values ahead of time (and removing such modifications within the function itself):

// Example usage(s)

public void MouseCamera(InputAction.CallbackContext context)
{
	// Check for correct context type, such as context.performed
	// to ensure that input is not inappropriately stacked on itself
	
	Vector2 delta = Vector2.Scale(context.ReadValue<Vector2>(), new Vector2(mouseSensitivityLateral, mouseSensitivityVertical));
	LookRotation(..., ..., delta);
}

public void AnalogCamera(InputAction.CallbackContext context)
{
	// Check for correct context type, such as context.performed
	// to ensure that input is not inappropriately stacked on itself
	
	Vector2 delta = Vector2.Scale(context.ReadValue<Vector2>(analogSensitivityLateral, analogSensitivityVertical), new Vector2()) * Time.deltaTime;
	LookRotation(..., ..., delta);
}