First Person Character Stutters when strafing and backpedaling

So I’ve been trying to create a smooth camera script that behaves closely to the camera behavior found in Doors, and ever since I’ve applied strafing animations to the character, I’ve encountered stuttered movement whenever the character is strafing or especially, backpedaling.

Here’s the issue in action.
https://i.gyazo.com/1280e1348838f304e57322ca87cd70cb.mp4

The portion of code that updates the camera in particular looks like this.

runService.RenderStepped:connect(function(Delta)

	if running then
		updatechar()
		if TargetAngleX >= 70 then
			TargetAngleX = lerp(TargetAngleX,70,math.clamp(0.25*(Delta / ExpectedDelta), 0, 1))
		elseif TargetAngleX <= -70 then
			TargetAngleX = lerp(TargetAngleX,-70,math.clamp(0.25*(Delta / ExpectedDelta), 0, 1))
		end
		CamPos = CamPos + (TargetCamPos - CamPos) *0.28 *(Delta / ExpectedDelta)
		AngleX = AngleX + (TargetAngleX - AngleX) *0.35 *(Delta / ExpectedDelta)
		local dist = TargetAngleY - AngleY 
		dist = math.abs(dist) > 180 and dist - (dist / math.abs(dist)) * 360 or dist 
		AngleY = (AngleY + dist *0.35*(Delta / ExpectedDelta)) %360
		cam.CameraType = Enum.CameraType.Scriptable
		tilt = lerp(tilt, math.rad((dist * 0.2)) , 0.1*(Delta / ExpectedDelta)) 
		
		local walkx = noise(xseed, clock() % 1000 * 0.5) * Roughness 
		local walky = noise(yseed, clock() % 1000 * 0.5) * Roughness 
		local walkz = noise(zseed, clock() % 1000 * 0.5) * Roughness 
		
		local sprintx = noise(xseed, clock() % 1000) * Roughness 
		local sprinty = noise(yseed, clock() % 1000) * Roughness 
		local sprintz = noise(zseed, clock() % 1000) * Roughness 
		if LookUp.IsPlaying ~= true then
			LookUp:Play(0,0.01,1)
		end
		if LookDown.IsPlaying ~= true then
			LookDown:Play(0,0.01,1)
		end
		if AngleX > 0 then
			LookUp:AdjustWeight(AngleX / 7,0)
			LookDown:AdjustWeight(0.01,0)
		elseif AngleX < 0 then
			LookUp:AdjustWeight(0.01,0)
			LookDown:AdjustWeight(AngleX / -7,0)
		else
			LookUp:AdjustWeight(0.01,0)
			LookDown:AdjustWeight(0.01,0)
		end
		cam.CoordinateFrame = CFrame.new(head.Position) 
			* CFrame.Angles(0,math.rad(AngleY),0) 
			* CFrame.Angles(math.rad(AngleX),0,0)
			* CFrame.Angles(0,0,tilt)
			* CFrame.Angles(math.rad(lerp(walkx,sprintx,SprintFactor)),math.rad(lerp(walky,sprinty,SprintFactor)),math.rad(lerp(walkz,sprintz,SprintFactor)))
			* HeadOffset -- offset

		humanoidpart.CFrame=CFrame.new(humanoidpart.Position)*CFrame.Angles(0,math.rad(AngleY),0)
	else game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default
	end

	if (cam.Focus.p-cam.CoordinateFrame.p).magnitude < 1 then
		running = false
	else
		running = true
		if freemouse == true then
			game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default
			input.MouseIconEnabled = true
			CursorGUI.Enabled = false
		else
			game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter
			input.MouseIconEnabled = false
			CursorGUI.Enabled = true
		end
	end

	if not CanToggleMouse.allowed then
		freemouse = false
	end

	cam.FieldOfView = FieldOfView
end

I’ve tried cutting down on any Z rotations and on the camera, and even tried lerping the HumanoidRootPart CFrame in an attempt to remove this stutter, but nothing removes it, at least not significantly.
I’ve even had a look at forking the original camera script before I came to this solution and I couldn’t figure it out, same with looking at using springs, and tweening doesn’t look appropriate for this purpose.

Does anyone here at least have a good idea or solution that I haven’t heard of yet?

1 Like