I’ve been trying to fix this issue for so long, anyone know how I can make my camera sway consistent on all framerates

local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Camera = workspace.CurrentCamera
local Turn = 0
local MaxSwayAmount = 6
local SwaySpeed = 3
local function UpdateCamera(deltaTime)
local MouseDelta = UserInputService:GetMouseDelta().X
local swayAmount = math.clamp(MouseDelta, -MaxSwayAmount, MaxSwayAmount)
Turn = Turn + (swayAmount - Turn) * SwaySpeed * deltaTime
Camera.CFrame = Camera.CFrame * CFrame.Angles(0, 0, math.rad(Turn))
end
RunService.RenderStepped:Connect(function(deltaTime)
UpdateCamera(deltaTime)
end)

deltatime is also literally present in the code, idk what im doing wrong

There was a fix explained in the framerate update post, however I don’t know if it works since my computer has the exact performance as a potato.

local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Camera = workspace.CurrentCamera
local Turn = 0
local MaxSwayAmount = 6
local SwaySpeed = 3
local TargetFPS = 60
local function UpdateCamera(deltaTime)
local MouseDelta = UserInputService:GetMouseDelta().X
local swayAmount = math.clamp(MouseDelta, -MaxSwayAmount, MaxSwayAmount)
Turn = Turn + (swayAmount - Turn) * SwaySpeed * deltaTime
Camera.CFrame = Camera.CFrame * CFrame.Angles(0, 0, math.rad(Turn))
end
RunService.RenderStepped:Connect(function(deltaTime)
UpdateCamera(math.rad(TargetFPS) * deltaTime)
end)

I can explain but TL;DR you need a different calculation method.

The issue is actually both your positive and negative term. For the positive term it is proportional to delta time to more fps means less sway so that means you actually have to turn the mouse more to compensate.

Then there is the issue of the negative term which is recursive sequence.

Turn = Turn + (swayAmount - Turn) * SwaySpeed * deltaTime
Turn += (swayAmount - Turn) * SwaySpeed * deltaTime
--Expand just the positive and negative turn
Turn += (swayAmount) * SwaySpeed * deltaTime
Turn = Turn - Turn *SwaySpeed*deltaTime --the negative term
a(n) = a(n-1) - a(n-1)*SwaySpeed*deltaTime --Desmos terms, the new value is determined by the old value of Turn

This can be graphed in desmos in 2 scenarios, 1 assuming fps is 60 and another assuming its 30 fps and the sway term Turn in degrees starts at 20 degrees. Sway speed is a constant value of 3.

As you can see it’s not the same meaning you need a better/different method.

I have remade it but instead of a recursive asymptotical formula replacing it with a linear term with a constant decrease of 10 degrees per second.

This is tbh not as good as the previous as the shape of the curve is not the same, so you should rework it perhaps by adding acceleration.

From this I recommend using another calculation method, perhaps a spring module or something instead which already takes into account acceleration and you can prevent overshoot by increasing dampening or removing velocity.

local RunService = game:GetService("RunService")
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer
local Camera = workspace.CurrentCamera
local Turn = 0
local MaxSwayAmount = 6
local SwaySpeed = 3
local decreaseSpeed = 10
local function UpdateCamera(deltaTime)
local MouseDelta = UserInputService:GetMouseDelta().X
local increaseSway = MouseDelta*0.1
Turn += increaseSway
local swayDecreaseIncrement = decreaseSpeed*deltaTime*math.sign(Turn)
if math.abs(swayDecreaseIncrement) >= math.abs(Turn) then--prevent overshoot
Turn -= Turn
else
Turn -= swayDecreaseIncrement
end
Camera.CFrame = Camera.CFrame * CFrame.Angles(0, 0, math.rad(Turn))
end
RunService.RenderStepped:Connect(function(deltaTime)
UpdateCamera(deltaTime)
end)