Gun sway and fps unlockers

Screen capture - b28acde6869dc5be5c6b4879a3caa175 - Gyazo - Without an fps unlocker
Screen capture - 04fc3d2e467b0eacff8a72795189362b - Gyazo - With an fps unlocker
(notice how the output is almost halved)

I’m currently using the formula given in this post, however as you can see from the links above, its not exactly ideal. Are there any better ways lerping CFrames independent of the frame rate?

Use an accumulator and adjust the rate:

Right, what exactly does this mean?

You run the code at constant rate, so it doesn’t and cannot go too fast when there is a fps unlocked.

Also in the tutorial I quoted above.

As in the code runs within the while do loop yes?
Result: Screen capture - 4122f15921db4294bae38ad3b3952bb0 - Gyazo

Looks like the rate is too slow making it laggy, make it higher should be 1/60.

You mean lower right?
At a rate of 0.01 it works fine without an fps unlocker, but with it on it’s very jittery.

It should also use renderstep instead of heartbeat.

Of course I am using renderstep. But it just doesn’t work well at all with an fps unlocker.
Is there any way of actually finding a good rate for both capped and uncapped FPS that doesnt involve just guessing numbers?

I guessed 1/60 because it’s 60 frames per second so 1 frame will be around 0.0166667 seconds.

As for the rate

It should be the same, I’m hypothesizing if the code runs at the same rate then the effects of the lerp should be the same on high and low fps.

Then post the code and make it clearer.

It appears to work a lot better now, however the gun model keeps jittering.

	Accumulated += dt
	while Accumulated >= Rate do
		Accumulated -= Rate

		ViewModel.Torso.CFrame = Camera.CFrame
		updateArm("Right")	-- Place arm on weapon

		if Character:FindFirstChildWhichIsA("Tool") then
			local rotation = workspace.CurrentCamera.CFrame:toObjectSpace(lastCameraCF)
			local x,y,z = rotation:ToOrientation()
			local Tool = ViewModel:FindFirstChildWhichIsA("Model")

			-- Calculate sway of gun
			swayOffset = swayOffset:Lerp(CFrame.Angles(math.sin(x)*mult,math.sin(y)*mult, 0), 0.1)

			ViewModel.Torso.CFrame = Camera.CFrame * swayOffset;
			Tool.InvisParts.BodyAttach.CFrame  = ViewModel:FindFirstChildWhichIsA("Model").InvisParts.BodyAttach.CFrame 
			lastCameraCF = Camera.CFrame

			-- Tool movement bobbing using springs
			local bob =,Bobbing(5),Bobbing(5))
			bobbing:shove(bob / 10 * (Character.HumanoidRootPart.Velocity.Magnitude / 10))
			local updatebob = bobbing:update(dt)
			ViewModel.Torso.CFrame  =ViewModel.Torso.CFrame:ToWorldSpace(, updatebob.X, 0))


Nice to know that,

Honestly got no clue with the variable naming like mult

TL;DR, make sure to use delta time, the spring module bobbing already uses delta time no need to adjust for that.

The issue is the sway which doesn’t use delta time, this should be within the while loop accumulator to make it adjust for delta time at constant rate independent of frame rate.

More detail:

However I suspect the bobbing is causing the jittering because of the :update(dt) within the while loop, I suspect the spring update dt is already adjusted for delta time so there is no need to put this section in the while loop. Currently I believe it’s updating too much in a single frame causing the jitter.

Only the lerp parts are not adjusted for the delta time because the lerp alpha is constant 0.1 and not based on delta time as seen here, this part should be rate limited to make it delta time based and framerate independent.

Jittering still seems to persists even with bobbing outside of the while loop?

Edit: The link above is the code with fps unlocker on, the code itself (with bobbing inside the while loop) works completely fine without an fps unlocker.

Bumping the post, still looking for solutions

Rereading your post, shouldn’t these two outputs of Accumulated be around the same?
Screenshot - b8b17523dd61d67b6ed7d916ffc3e103 - Gyazo (Without FPS unlocker)
Screenshot - 2a4971c1323eb28223c2cc4852e1c96a - Gyazo (With FPS unlocker)

local Rate = 1/60 -- 0.166666 etc
local Accumulated = 0

	Accumulated += dt
	while Accumulated >= Rate do
		Accumulated -= Rate

Try another method of doing sway instead of keeping the lerp one.

This one uses spring to do the sway.

I’m busy can’t answer the previous question for now.

Referencing this piece of code, perhaps you could try replacing the alpha value of 0.1 with something along the lines of 6*dt, representing the alpha value per second you feel works at presumably 60 fps, or 60 fps * 0.1 a = 6
This might make it completely freak out for people with and FPS lower than like 30, but perhaps we will be able to take a partial solution and build upon it, given this topic seems to have died a bit (This is assuming you remove the accumulator)

If youre comfortable sharing some of the models Id love to not waste your time suggesting 50 different things which could be tested in just 10 minutes, additionally, but this is by no means necessary

  1. I’m not exactly sure how changing the alpha value would fix the problem, wouldn’t it just be completely different at different FPS?
    I tested it anyway with both capped and uncapped FPS, with the accumulator removed:
    Screen capture - 4e9d01ce0d046522d8c69869b9285597 - Gyazo - Capped FPS
    Screen capture - 0cfa6df05ffc2940b2776b4ee03fa38f - Gyazo - Uncapped FPS

I’d also prefer to find a working solution with the accumulator because, as shown in the links above, the bobbing is also more noticeable with FPS uncapped.

I believe this problem has already been solved before within this tutorial which uses the same delta time strategies to account for the additional fps me and @PapaBreadd have been trying to suggest the entire time.

One such method is the spring method I linked above and also found in the fps framework tutorial below:

Theoretically this should work because it’s been there for a long time and made by a experienced fps developer. If it doesn’t work for you then…

1 Like