Playermodule Camera Stutter due to inputchanged lag from CameraInput module

The deltas recieved from inputchanged events are lagging behind due to performance degradation. The delta’s become too big and inconsistent which causes stutter. I also created a seperate testplace to check my flight script with almost no meshes and it still happens.

I tracked the problem down to CameraInput of Playermodule. I know this because I wrote my own camera script with UserInputService:GetMouseDelta() *0.01 and it worked with little to no stutter, but when I plugged in the inputs from CameraInput.getRotation() from the Playermodule’s CameraInputs the camera started stuttering. I modified the getRotation function to match the output of UserInputService:GetMouseDelta() *0.01 to see if any differences occur.

local ROTATION_SPEED_MOUSE = Vector2.new(0.01, 0.01) -- (rad/inputdelta)
local ROTATION_SPEED_POINTERACTION = Vector2.new(1, 0.77)*math.rad(7) -- (rad/inputdelta)
local ROTATION_SPEED_TOUCH = Vector2.new(0.01, 0.01) -- (rad/inputdelta)

	function CameraInput.getRotation(dt, disableKeyboardRotation: boolean?): Vector2
		local inversionVector = Vector2.new(1, UserGameSettings:GetCameraYInvertValue())

		-- keyboard input is non-coalesced, so must account for time delta
		local kKeyboard = Vector2.new(keyboardState.Right - keyboardState.Left, 0) * dt
		local kGamepad = gamepadState.Thumbstick2 * UserGameSettings.GamepadCameraSensitivity * dt

		local kMouse = mouseState.Movement
		local kPointerAction = mouseState.Pan
		local kTouch = touchState.Move

		if disableKeyboardRotation then
			kKeyboard = Vector2.new()
		end

		local result =
			kKeyboard*ROTATION_SPEED_KEYS +
			kGamepad*ROTATION_SPEED_GAMEPAD +
			kMouse*ROTATION_SPEED_MOUSE +
			kPointerAction*ROTATION_SPEED_POINTERACTION +
			kTouch*ROTATION_SPEED_TOUCH
		
		local inputMouse = UserInputService:GetMouseDelta() *0.01
		local data = result*inversionVector
		
		if data.Magnitude > 0 and inputMouse.Magnitude > 0 then
			if data.X ~= inputMouse.X or data.Y ~= inputMouse.Y then
				print(data,inputMouse)	
			end
		end	

		return result*inversionVector
	end
				if #unsunkTouches == 1 then
					if touches[input] == false then
						local delta = input.Delta
						touchState.Move = Vector2.new(delta.X, delta.Y) -- changed += to =
					end
				end

The inconsistent outputs of UserInputService.InputChanged:Connect(inputChanged) is much higher then UserInputService:GetMouseDelta() *0.01.



When changing the return value of CameraInput.getRotation() to UserInputService:GetMouseDelta() *0.01 the stutters went away.

The microprofiler reveals strange spikes happening which is not from my scripts. I think thee spikes cause performance degradation and lag UserInputService.InputChanged:Connect(inputChanged)





My understanding is that when performance degrades, inputchanged takes too long to send an output which causes stutters due to high deltas. This isn’t something I can fix. It must be a core engine issue. I also closed off any particles in the game and it still didn’t help. Changing the flight script also didn’t help. I also set the networkownership of baseparts to character and it still didn’t help. My custom camera has a smoothing Vector3 point lerping to the predicted offset of the player and it also stuttered with the inputs from CameraInput module. Hopefully this is enough to detect and solve the issue. Good luck!

Expected behavior

A private message is associated with this bug report

Hi!

Thanks for the report. Does the same spike happen if you turn on the rollout for Workspace.PlayerScriptsUseInputActionSystem? We’ve converted a lot of the cross platform code into the engine with IAS which should improve performance.

Good evening,

I converted my input access to be compatible with IAS, but the issue still presists.

local module = {}

local starterPlayer = game:GetService("StarterPlayer")
local inputContexts = starterPlayer.PlayerModule.InputContexts

local cameraContext = inputContexts.CameraContext
local characterContext = inputContexts.CharacterContext

local cameraRotation = cameraContext.CameraRotationAction
local moveAction = characterContext.MoveAction

function module.GetLocalPlayerMoveVector(player):Vector2
	return moveAction:GetState()
end

function module.GetCameraDelta()
	return cameraRotation:GetState().X/50
end

return module

From 0-9 seconds, you can see the stutter. After that the CPU spikes to red and inputs gets fixed, but this is only temporary because the stutter does return until the next spike.

The old Playermodule also had the exact same issue. Whatever the problem is it got carried over. It might be syncronization issue of inputs with the renderstep of camera.