FreeLookCamera With Gamepad+Mouse Support, Jittery Mouse on Export

Hello,

We are building a 3D platforming game and are using a Cinemachine FreeLookCamera. Since we are using the new input system and the game mainly targets gamepads, we set the m_X/YAxis.InputAxisName to blank, and manually set the Axis Value every Update to the right stick value. With some some tweaks to acceleration/deceleration speed, using SpeedMode MaxSpeed, and doing some deadzone checks, gamepad feels great. It runs super smoothly across any frame rate, and feels like any game camera should when operated by a gamepad.

We have run into issues when adding mouse support. Our first approach was to simply pipe in the Mouse X and Mouse Y axis values the same way we were sending the Gamepad axis values along with different acceleration/deceleration/MaxSpeed values. The mouse control felt off. It started moving weird, it stopped moving weird, we got a lot of negative player feedback with this approach.

My next approach and the one I’ve currently settled on is to, if detecting mouse input, to overwrite m_X/YAxis.InputAxisName to Mouse X/Y respectively, and simply let Cinemachine handle the inputs natively. This feels a little better, but still feels not nearly as smooth/responsive as standard PC games should feel, especially since we are seeing framerates in the literal thousands on my rig. If I set the acceleration values too low, I see jittery mouse movement. Too high, and the camera feels sluggish. I can’t seem to find any magic number.

In my research I was suggested InputValueGain for the SpeedMode parameter, and I tried it. After some fiddling I got it to feel pretty good in the editor! The camera felt very snappy and smooth. I built the game for windows, with the released build seeing higher frame rates, and suddenly the camera was insanely jittery as I moved the mouse. No matter what I set the acceleration to (I’ve tried 0, 0.05, 0.1, 0.3, 0.5, and 1.0) it seems to start and stop and start and stop again.

I’ve tried scaling inputs by deltaTime, I’ve tried manually writing straight to the Axis Value based on some folks’ suggestions, and tried several other combinations of the above with all different settings, and while some of it has felt smooth in editor, I haven’t found a single solution that feels nice in export.

Any recommendations?

Have you tried limiting the frame rate? Are thousands really necessary?

Ideally I would like to support uncapped frame rate. I tried using QualitySettings.vSyncCount = 1 to have the framerate match the display (I have a 175hz Monitor and don’t want to cap at 60) but couldn’t seem to get that to work. Is there some other way I should get Unity to match the display frame rate?

I’ll also test with a static frame rate to see if that helps.

To me it is strange that the game running at high performance results in a jittery camera though :confused:

I’m not an expert on how to cap the framerate, so can’t really help you there.

With a very high framerate you might be running into precision issues in the input signal. Maybe the solution is to figure out a way to smooth that before sending it to CM.

Capping the frame rate did it! Since I still wanted to match display refresh rate I ended up using the following line of code during a Start():
Application.targetFrameRate = Screen.currentResolution.refreshRate;

With the capped frame rate, setting the InputAxisNames to Mouse X and Mouse Y, setting the SpeedMode to InputValueGain, and tweaking the MaxSpeed X to around 6f and MaxSpeed Y to around (6f / 150f), I’ve settled on something which feels good. We’ll still be exposing horizontal and vertical camera sensitivity options to players, but that absolutely seems to have solved the issue.

2 Likes