Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to alter "RenderStepped:wait()"?

I want to have the smoothest camera movement in my game as possible. This is how I do it currently (in a local script):

while wait(1/30) do --minimum time for wait() function
	--code setting the camera's CameraSubject to a part
end

However, it is choppy at times. I recently learned about...

game:GetService("RunService").RenderStepped:wait()

...where it can run at 60 FPS.

So I decided to give it a try like this:

while true do
	--code setting the camera's CameraSubject to a part
	game:GetService("RunService").RenderStepped:wait()
end

This, however, is WAY too fast, and, as a result, the screen flickers. It's not aesthetically pleasing.

How can I alter RenderStepped:wait() to have the perfect FPS and be somewhere in between? Putting a number such as 2/60 inside of the wait() in this special RenderStepped function does not change anything.

1 comment

0

Actually, the smoothest cameras can go is when you use Interpolate.

2 answers

✓ Accepted answer

You can just do it twice, but that defeats the point. It will be basically like using wait() at that point -- you won't be taking advantage of the difference, so there would be no point in making the chance.

If it works differently than before, then the design didn't take into account the time pausing.

For instance, consider this code:

local x = 0
while true do
	wait(1)
	x = x + 1
	part.CFrame = CFrame.new(x, 10, 0)
end

This will make the part move 1 stud per second to the right. But it will be incredibly choppy, since it only moves it only once per second. We can make it faster, say, 30 times a second:

local x = 0
while true do
	wait()
	x = x + 1
	part.CFrame = CFrame.new(x, 10, 0)
end

... but now it's also zipping along 30 times faster. We want it to do the same thing as before -- just smoother. The problem is, the changing in between doesn't care how much time is passing. We need it to take. That x = x + 1 needs to scale according to how much time has passed.

Luckily, that's easy:

local x = 0
while true do
	local elapsed = wait()
	x = x + 1 * elapsed
	part.CFrame = CFrame.new(x, 10, 0)
end

Unfortunately, RenderStepped:wait() won't give us how much time has elapsed. You could either assume it's 1/60, or you can measure it using tick():

local start = tick()
game["Run Service"].RenderStepped:wait()
local elapsed = tick() - start

If you need to limit the amount of time you actually wait from the RenderStepped event then you should use the tick function!

The tick function returns the amount of time, in seconds, since the epoch. So you can use this to compare times! Make a variable for the tick() before the event, then after. And compare the after - before with a number to limit the wait time!

Remember: The RenderStepped event waits every 1/60th of a second, so say you compare the ticks with 60, you'd be checking if 1 second had passed.

local before = tick() --Before

game:GetService('RunService').RenderStepped:connect(function()
	local after = tick() --After
	local compare = after - before --Get the difference
	if after - compare >= 10 then --Compare
		
		--Do your camera code

	end
end)

I suggest you also look into Camera Interpolation!

This discussion is preserved as it was. New answers, comments, and votes are closed.