CameraRelative RotationType very jittery

Hello, everyone.
I am currently working on an over-the-shoulder (OTS) gun system, and I am running into an issue. I want the player to face where the camera is pointing, very similar to how shift lock works. I discovered the UserGameSettings service, and the UserGameSettings.RotationType property.

In theory, setting this property to CameraRelative should make it behave very similar to shift lock. But in practice, the player jitters quite a bit, making it look very ugly. Attached is a demonstration: camerarelative jitter - Album on Imgur (note: the red dot is not in the game, just a recording artifact)

As seen, this property has a lot of jitter, which does not exist in normal shift lock mode.

Here is the relevant segment of the LocalScript of my gun:

local function updateCrosshair(gap :number, transparency :number?)
	local t = crosshair.Top
	local b = crosshair.Bottom
	local l = crosshair.Left
	local r = crosshair.Right
	local vp = workspace.CurrentCamera.ViewportSize
	local x = vp.X/2
	local y = vp.Y/2
	t.Size = UDim2.fromOffset(4, 20)
	b.Size = UDim2.fromOffset(4, 20)
	l.Size = UDim2.fromOffset(20, 4)
	r.Size = UDim2.fromOffset(20, 4)

	t.Position = UDim2.fromOffset(x-2, y-10-gap)
	b.Position = UDim2.fromOffset(x-2, y-10+gap)
	r.Position = UDim2.fromOffset(x-10+gap, y-2)
	l.Position = UDim2.fromOffset(x-10-gap, y-2)

	t.Transparency = transparency
	b.Transparency = transparency
	r.Transparency = transparency
	l.Transparency = transparency
end

gun.Equipped:Connect(function(mouse :Mouse)

	local isAiming = false
	local camOffset = 0
	local camTweenInfo = TweenInfo.new(.2, Enum.EasingStyle.Quad, Enum.EasingDirection.InOut)
	local elapsed = 0
	UserInputService.MouseIconEnabled = false
	RS_Cam_Connection = RunService.Heartbeat:Connect(function(deltaTime: number)
		UserInputService.MouseBehavior = Enum.MouseBehavior.LockCenter
		local curOffset = humanoid.CameraOffset
		if isAiming and curOffset.Magnitude < 3 then
			elapsed = math.min(elapsed+deltaTime, camTweenInfo.Time)
			local alpha = TweenService:GetValue(elapsed/camTweenInfo.Time, camTweenInfo.EasingStyle, camTweenInfo.EasingDirection)
			updateCrosshair(SMALL_CROSSHAIR_GAP, 1 * (1-alpha))
			camOffset = 3 * alpha
		elseif not isAiming and curOffset.Magnitude > 0 then
			elapsed = math.max(elapsed-deltaTime, 0)
			local alpha = TweenService:GetValue(elapsed/camTweenInfo.Time, camTweenInfo.EasingStyle, camTweenInfo.EasingDirection)
			updateCrosshair(SMALL_CROSSHAIR_GAP, 1 * (1-alpha))
			camOffset = 3 * (alpha)
		end
		humanoid.CameraOffset = Vector3.new(camOffset, 0, 0)
	end)

	local function aim(actionName :string, inputState :Enum.UserInputState, input :InputObject)

		if actionName==AIM_ACTION then
			if input.UserInputType == Enum.UserInputType.MouseButton2 then
				if inputState == Enum.UserInputState.Begin then
					crosshair.Enabled = true
					UserGameSettings.RotationType = Enum.RotationType.CameraRelative
					updateCrosshair(SMALL_CROSSHAIR_GAP, 1)
					isAiming = true
				elseif inputState == Enum.UserInputState.End then
					isAiming = false
					UserGameSettings.RotationType = Enum.RotationType.MovementRelative
					crosshair.Enabled = false
					isShooting = false
				end
			end
		end
	end

While I do plan on using the CameraRelative property as a placeholder until I create a better “look at and aim” system (any suggestions on where to start with that would be neat), I still want to have this work for now, especially if it will help make it easier to create that system in the future.

Please let me know if there is any way to fix the jitter, or at the very least, achieve the same shift-lock-esque effect with a different method that has no jitter.