Mouse sensitivity is still linked to framerate, as are jump and gravity

Brendan

New member
I hate to post another thread on this topic, but this has been brought up frequently on this forum over the years and on the Discord and it hasn't been resolved.

Essentially, if you set UltimateCharacterLocomotion's Update Location to Fixed Update then the mouse sensitivity in-game becomes linked to the framerate. This bug has been in UCC for several years (as long as I've used it) and is still present in the latest version.

Unity version: 2020.3.6f1
UCC version: 2.3.3 June 17th release

Replication steps:
- Set up UCC in first person combat mode in a blank scene with the framerate uncapped.
- Add a ton of objects on one side of the scene so that the framerate drops considerably when you look at them.
- Build the game and start it up.
- Move the mouse slowly and at a constant speed to rotate your character in a circle.
- You will notice that your camera does not rotate at a consistent rate. It quickly skips over the low framerate area as the mouse sensitivity jumps as the framerate goes down.

Setting the update location to Update solves this but also comes with its own bizarre bug where jumping force and gravity become linked to the framerate. If you reduce your framerate, you can actually jump higher and will fall more slowly. Conversely, players with 240hz monitors running at 240 fps can only jump about 2cm off the ground. The only way to solve this somewhat seems to be to lock the frame rate to 60, which produces consistent results everywhere but isn't really an acceptable solution in 2021 when people have 240hz monitors and graphics cards that use more electricity than Lichtenstein.

So right now I have a choice between having rotation broken or jumping and falling broken. I suspect there's something wrong with how TimeUtility.FramerateDeltaTime is being used. The jump height bug still applies all of the jump force in one frame as specified in the Jump's parameters, for example, but the height seems to be being scaled by FrameRateDeltaTime somehow.

Any thoughts?
 
Update: Figured out the jumping bug. Jumping sets m_ExternalForce which in turn is used in CharacterLocomotion.UpdatePosition as so:
var deltaTime = TimeScaleSquared * Time.timeScale * TimeUtility.FramerateDeltaTime;
m_MoveDirection += m_ExternalForce * deltaTime + (m_MotorThrottle * (UsingRootMotionPosition ? 1 : deltaTime)) - m_GravityDirection * m_GravityAmount * deltaTime;
The motor throttle, external force, and gravity are all scaled by TimeUtility.FramerateDeltaTime here, so that's where that bug is happening. All the force-based code is using a frame basis and then it looks like it's try to convert it into a time-basis using FramerateDeltaTime? This assumes that anything applying a force is actually intending to apply a force over time, which isn't always the case. Jumps are meant to apply a single specific force push, for example, so the force being applied shouldn't be multiplied by anything.

Even after fixing that issue so that the same total force is always applied regardless of framerate, soft forces over multiple frames won't work consistently in non-fixed timestep because higher framerates will apply the forces more quickly. Obviously using FixedUpdate would solve all of this, but the fixedupdate option still has the broken mouse sensitivity.
 
I just went through my sensitivity test and realized there was an error in the test script so it was reporting incorrect results. I am able to see what you are saying. 2.3.4 hasn't been released on the Asset Store yet so I'll get this fixed in that version. If it's an easy fix I'll post it here otherwise will send you a PM to verify that it is fixed before release.
 
Justin and I have messaged back and forth a bit about this issue, and I think I've got to the bottom of it. It's actually not an Opsive problem, it appears to be a bug in Unity's Input system. Unity.Input.GetAxisRaw("Mouse X") and Unity.Input.GetAxisRaw("Mouse Y") don't actually return raw numbers, they are scaled based on framerate for some reason so they can't be reliably used in FixedUpdate.

By coincidence we just finished implementing Rewired, which uses a different input system and UCC already has integration for it. That completely fixed the problem. After all these years and all the threads and discord messages about this, it's bizarre to find out it's probably a bug in Unity. Happy to have a solution, though!
 
So is there a solution for using Unity's new Input System?

Kind of feeling that I should just jump over to Rewired as well as I have yet to really get into setting up Unity's new Input System
 
Last edited:
Justin and I have messaged back and forth a bit about this issue, and I think I've got to the bottom of it. It's actually not an Opsive problem, it appears to be a bug in Unity's Input system. Unity.Input.GetAxisRaw("Mouse X") and Unity.Input.GetAxisRaw("Mouse Y") don't actually return raw numbers, they are scaled based on framerate for some reason so they can't be reliably used in FixedUpdate.

By coincidence we just finished implementing Rewired, which uses a different input system and UCC already has integration for it. That completely fixed the problem. After all these years and all the threads and discord messages about this, it's bizarre to find out it's probably a bug in Unity. Happy to have a solution, though!

Have you reported this to Unity? Please do, thank you.
 
So is there a solution for using Unity's new Input System?

Kind of feeling that I should just jump over to Rewired as well as I have yet to really get into setting up Unity's new Input System
I'm not sure if this issue is present in the new Input system, we were using the standard Unity input system and then switched to Rewired. I believe Rewired uses different systems under the hood depending on platform.

Have you reported this to Unity? Please do, thank you.
I will put together a minimum viable build of this at some point and report it. It's bizarre that Unity's GetAxisRaw would work like this, it must be having effects on a lot of projects and assets.
 
@Brendan I'm using Rewired, and I get really choppy mouse aiming, pretty much all the time when moving/firing.

It seems reasonably smooth when ONLY mouse aiming, but as soon as I fire or move, it's terribly jumpy, stuttery, and just unplayable....

Do you know if my problem is related? I've played around with the 'Rewired Input' component settings, as well as UltimateCharacterLocomotion motor settings, the individual weapon settings, the camera settings... Nothing really makes a difference
 
Last edited:
hi @Brendan and @Justin - Was this resolved in the end?

If so, I'll probably end up needing to cherry-pick code as we're a fair few versions behind in our game that's out in production.
 
Top