How can I make my script work with an FPS unlocker?

And multiplying your values by the delta time will make it so that they go different speeds for different frame rates. It essentially just multiplies it by time passed so the longer between frames the more effect it has.

this worked, but itā€™s not giving the same result i really wanted.
this is what iā€™m aiming for

sorry if iā€™m being so specific

update: nevermind it broke again

your edit above crashed my entire client the second i began to walk

So how is it different than you envision? I only see what you want, not what you have.

i dunno if it helps, but iā€™m actually using the realism framework by clonetrooper in the game i am attempting to make, not sure if itā€™s affecting this script, it worked without an fps unlocker at first

apologies, it did work. it broke the first time but for some reason began working again afterward.
regardless, the camera still shakes really fast when you move while an fps unlocker is on

I replied with this change, but you might not have seen it.

Here is the full code with those changes:

while true do
	wait();
	if game.Players.LocalPlayer.Character then
		break;
	end;
end;
camera = game.Workspace.CurrentCamera;
character = game.Players.LocalPlayer.Character;
Z = 0;
damping = character.Humanoid.WalkSpeed / 2;
PI = 3.1415926;
tick = PI / 2;
running = false;
strafing = false;
character.Humanoid.Strafing:connect(function(p1)
	strafing = p1;
end);
character.Humanoid.Jumping:connect(function()
	running = false;
end);
character.Humanoid.Swimming:connect(function()
	running = false;
end);
character.Humanoid.Running:connect(function(p2)
	if p2 > 0.1 then
		running = true;
		return;
	end;
	running = false;
end);
character.Humanoid.Died:connect(function()
	running = false;
end);
function mix(p3, p4, p5)
	return p4 + (p3 - p4) * p5;
end;
while true do
	local step = game:GetService("RunService").RenderStepped:wait();
	fps = (camera.CoordinateFrame.p - character.Head.Position).Magnitude;
	if fps < 0.52 then
		Z = 0;
	else
		Z = 0;
	end;
	if running == true and strafing == false then
		tick = tick + character.Humanoid.WalkSpeed / 102 * (30*step);
	else
		if tick > 0 and tick < PI / 2 then
			tick = mix(tick, PI / 2, 0.9);
		end;
		if PI / 2 < tick and tick < PI then
			tick = mix(tick, PI / 2, 0.9);
		end;
		if PI < tick and tick < PI * 1.5 then
			tick = mix(tick, PI * 1.5, 0.9);
		end;
		if PI * 1.5 < tick and tick < PI * 2 then
			tick = mix(tick, PI * 1.5, 0.9);
		end;
	end;
	if PI * 2 <= tick then
		tick = 0;
	end;
	camera.CoordinateFrame = camera.CoordinateFrame * CFrame.new(math.cos(tick) / damping, math.sin(tick * 2) / (damping * 2), Z) * CFrame.Angles(0, 0, math.sin(tick - PI * 1.5) / (damping * 20));
end;

These changes get the step time then use the step time to scale the tick change per frame. This makes the bobble time dependent, not frame rate dependent. I re-read the code, the dampening code shouldnā€™t give any problems.

Some code suggestions:

Instead of using this to wait for the character:

while true do
	wait();
	if game.Players.LocalPlayer.Character then
		break;
	end;
end;

use:

game:GetService("Players").LocalPlayer.CharacterAdded:Wait()

Instead of using a loop, use a connection. That one is a bit harder to explain, using a loop is fine.

2 Likes

instead of doing this, you should put your while true loop inside of

RenderStepped:Connect(function(DeltaTime)
  ... Your code here
end)

And then use DeltaTime math for any values that increase too rapidly.

edit: To clarify this is how you should have been doing this in the first place.

also edit: Iā€™ll explain DeltaTime to you.

DeltaTime is the time difference between two reference points in time. (such as time since last frame)
In our case, DeltaTime is ā€œFrameTimeā€ which correlates to the difference in time (how long) the last frame took.
If you were to sum up the DeltaTime, youā€™d find that it correlates exactly to seconds.
Iā€™ll be referring to DeltaTime as DT hereafter.
The 60FPS limit of roblox has an average DT of around 1/60 (0.016ā€¦7), as is expected because itā€™s 60 Frames Per Second.

DT Math is essentially defining the increase per second(Step) & the simple formula for the increase over time for the value (tick for you) as Step * DT;
Example:

tick = tick + ((Character.Humanoid.WalkSpeed / 102) * Step)

and while I was writing this edit, I noticed a bad suggestion.
@TheH0meLands, donā€™t use Heartbeat for Camera updates.

this weirdly offsets my camera to the side

1 Like

???

Whoops! My bad, I accidentally used division instead of multiplication:

This

should be
tick = tick + character.Humanoid.WalkSpeed / 102 * (30*step);

I updated the code. Working with units of frames per second and seconds per frame gets confusing :sweat_smile:

1 Like

that seemed to fix it, albeit the bobbing is a lot slower now.
should i just change the numbers on that line? and which one would make it faster by increasing it or decreasing it?

1 Like

You should change the 30 here:

The code converts your frame dependent code to time dependent code assuming the FPS is 30 normally, so changing that changes the speed.

Maybe try using 40-50 FPS instead of 30. You can also just check the FPS of the game you tested it in to find the value to convert it exactly.

Edit:

You can also use this code to get the FPS:

game:GetService("RunService").RenderStepped:Connect(function(step)
    local fps = 1/step
    -- code to display FPS, ex: print(fps), script.Parent.Text = fps
end)
1 Like

alright, iā€™ll play around with it

thank you so much for the help!! iā€™ll mark the topic as solved
thank you to everyone for the help/advice

1 Like

Oh thank you for this info. Didnā€™t know. Thanks

No problem man, Iā€™m happy to assist.

Since idk if this was a slip up due to not knowing why or just not checking the code, Iā€™m gonna explain it anyways since Iā€™m bored.

Heartbeat fires after RenderStepped, RenderStepped fires prior to frame rendering.

1 Like