Camera gets permanently offset after changing WobbleStrength

I was trying to create my own Camera Sway script which includes CameraWobble (makes the camera slowly move in all directions a bit). Whenever I change the value for the WobbleStrength during run time the camera permanently gets offset like this:

I haven’t found a solution on the devforums for this issue. So far I’ve only tried resetting Camera.CameraSubject to the character’s Humanoid but that didn’t work

This is the code I use for the CameraSway

RunService:BindToRenderStep(
	'CameraSway', Enum.RenderPriority.Camera.Value + 1, 
	function(RenderTime: number)
		local MouseDelta = GetMouseDelta()
		local Time = workspace:GetServerTimeNow()
		local WobbleTime = Time * WobbleSpeed
		
		Turn = Lerp(Turn, math.clamp(MouseDelta.X, -Clamp, Clamp) * MouseStrength, RenderTime * Strength)
		Camera.CFrame = 
			Camera.CFrame 
			* CFrame.Angles(0, 0, math.rad(Turn)) 
			* CFrame.new(
				math.sin(WobbleTime) * WobbleStrength,
				math.cos(WobbleTime) * WobbleStrength, 0
			)
	end
)

Any help is appreciated!

1 Like

i’m not entirely sure if this is going to help, but try making something like baseCFrame = Camera.CFrame outside, and then just edit it like

Camera.CFrame = baseCFrame * CFrame.Angles … etc.

How is this exactly going to resolve my problem? It’s just obtaining the Camera’s CFrame which will only be used once. In my opinion it’s just a waste

if you update relative to the previous cframe then any irregularities will be there forever

but if you calculate some offset from the base cframe every time then it will recover naturally

I figured that on my own, but how would I do that?

well for one i don’t know why you’re using GetServerTimeNow, this is something you’d use tick() or os.clock() for. unless for some reason you need everyone’s camera shake to be synced up.

anyway, when you change WobbleStrength, the issue is that the “center” changes mid-wobble - like if the sine function returns 1, WobbleStrength is say, 3, the camera offset is 3. but then when you change WobbleStrength down to 1, the camera offset is still 3, but can no longer move back down because WobbleStrength isn’t high enough when sine is -1, the offset is -1, coming down from 3 - thus the offset is permanently changed to be around 2.

my suggestion is to not change WobbleStrength directly - instead, lerp between the maximum camera shake output and the base camera cframe, scaling the wobble instead of directly changing it. something maybe like this:

RunService:BindToRenderStep(
	'CameraSway', Enum.RenderPriority.Camera.Value + 1, 
	function(RenderTime: number)
		local MouseDelta = GetMouseDelta()
		local Time = tick() -- no need for GetServerTimeNow
		local WobbleTime = Time * WobbleSpeed
		
		Turn = Lerp(Turn, math.clamp(MouseDelta.X, -Clamp, Clamp) * MouseStrength, RenderTime * Strength)
		Camera.CFrame = 
			Camera.CFrame:Lerp(
			    Camera.CFrame * CFrame.Angles(0, 0, math.rad(Turn)) 
			    * CFrame.new(
				    math.sin(WobbleTime) * WobbleStrength,
				    math.cos(WobbleTime) * WobbleStrength, 0
		    	), WobbleScaleFactor -- between 0-1
            )
	end
)