Cinemachine virtual camera rotates faster depending on the FPS

Rotating the virtual camera is way too fast with the mouse when the FPS is low, and its at a decent speed when the FPS is high. Also sometimes it randomly rotates even faster for a second no matter how high the FPS is. However the FPS doesn’t affect the gamepad’s rotation speed. When I change the cinemachine brain’s Update method from Smart Update to Fixed Update it kinda fixes the fps problem but then the camera still rotates faster for a second sometimes. How can I fix this problem?

Unity 2021.3.8f1
Input System 1.4.2
Cinemachine 2.8.9

That’s because the default Input Actions that ship with the input system do not deliver the same kind of values for mouse delta as they do for other devices, so it’s impossible for Cinemachine to handle both kinds of input agnostically.

The key issue is that mouse deltas will be larger for low framerates and smaller for high framerates. This is not the case for other kinds of input, so Cinemachine cannot compensate for it without knowing too much detail about the input source - which would break the abstraction that the input package brings.

One possible fix is to implement a processor for the mouse delta binding in the input system. The processor needs to scale the input by the inverse of deltaTime, making it framerate-independent. Here is an example of a custom processor that does that. Add it to your project, then add the processor to the mouse delta binding of the input action, as shown below.

using UnityEngine;
using UnityEngine.InputSystem;

/// <summary>
/// This processor scales the value by the inverse of deltaTime.
/// It's useful for time-normalizing framerate-sensitive inputs such as pointer delta.
/// </summary>
#if UNITY_EDITOR
[UnityEditor.InitializeOnLoad]
#endif
class DeltaTimeScaleProcessor : InputProcessor<Vector2>
{
    public override Vector2 Process(Vector2 value, InputControl control) => value / Time.unscaledDeltaTime;

    #if UNITY_EDITOR
    static DeltaTimeScaleProcessor() => Initialize();
    #endif

    [RuntimeInitializeOnLoadMethod]
    static void Initialize() => InputSystem.RegisterProcessor<DeltaTimeScaleProcessor>();
}

If your camera is bound to a read-only input action from the DefaultInputActions asset, you’ll first need to copy that asset into your project so that you can modify it, then re-assign the input actions to the camera.

1 Like