Making EZ Camera Shake run independent of FPS?

I’ve been having an issue with EZ Camera Shake, the module works fine overall but I’ve come to the conclusion that the higher your FPS is, the more hectic / intensive your camera shake is. I looked into the module’s code and figured out that it’s running on a bindtorenderstep and I’ve tried various methods of making the function run every 1/60th of a second but I haven’t had much luck, with it either capping my FPS or causing the camera shake to get pretty glitchy.

Here’s the renderstepped function inside of EZ Camera Shake which is what I’m looking at:

function CameraShaker:Start()
	if (self._running) then return end
	self._running = true
	local callback = self._callback


	game:GetService("RunService"):BindToRenderStep(self._renderName, self._renderPriority, function(dt)
			profileBegin(profileTag)
			local cf = self:Update(dt)
			profileEnd()
			callback(cf)	
	end)
end

If anyone could help me allow this to run consistently around all framerates I’d majorly appreciate it.

2 Likes

I’m not completely sure how to fix this myself but I found a video that explains how the task scheduler works and proper ways of writing code to fit with it. You might be able to use some of these concepts to fix your problem. (Also, he explains that using while true do for this stuff is bad but u don’t have any of that in the code that I can see so that part of the video won’t really be relevant to your situation)

Hope this helps:

This happens because the shaker rotates the camera, which means the next frame the camera will be rotated around the character. This happens more frequently the more fps you have, which is why the shake seems more intense on higher fps. There are two solutions. The first is to just have it not rotate the camera, which is pretty simple to do so I won’t show how to do it. This may be preferable sometimes, but if you want to rotate the camera then you must revert the rotation during the next frame before the camera updates. It would look something like this:

local RunService = game:GetService("RunService")

local CameraShaker = require()

local PreviousCF
local Shake = CameraShaker.new(Enum.RenderPriority.Last.Value, function(offset)
	local camera = workspace.CurrentCamera
	
	if camera then
		local current = camera.CFrame
		camera.CFrame = current * offset
		PreviousCF = current
	else
		PreviousCF = nil
	end
end)
RunService:BindToRenderStep("ShakeReset", Enum.RenderPriority.First.Value, function()
	local camera = workspace.CurrentCamera
	
	if PreviousCF and camera then
		camera.CFrame = PreviousCF
	end
end)

Shake:Start()

while wait(2) do
	Shake:Shake(CameraShaker.Presets.Explosion)
end

(pressed send too early… whoops)

7 Likes