Hello.
I’m working on a first-person shooter, and one problem I’ve come across is the shooting while loop for automatic weapons is tied to what I think is the player’s framerate. This usually occurs when I shoot a character, which I find to be somewhat performance intensive. Here’s a video of the issue;
(the output shows the wait time between the beginning and end of the loop)
I want to know what the solution to this problem is, or at least if there is a better approach to making this less noticable. Here’s the code to the client shooting.
local t
while userInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton1) do
t = tick()
if
weaponInfo
and weaponInfo.Ammo.Value > 0
and weaponInfo.OnCooldown.Value == false
and weaponInfo.Reloading.Value == false
then
local result = getFireDirection()
actionVisualFunctions[1]() -- viewmodel visuals when shooting
weaponActionEvent:FireServer(1, result ~= nil and result.Position or currentCamera.CFrame.Position + currentCamera.CFrame.LookVector * 16384)
end
if not weaponIdInfo[weaponId].Auto then break end
task.wait()
print(t - tick())
end
I’ve heard of deltaTime, but I’m not sure how to implement it to the loop.
If I used RenderStepped, it would still be tied to framerate, specifically the player’s. Using Stepped would tie the loop to the framerate of the physics simulation. If this is the most precise option, I will use it, but I’m pretty sure there are more precise loops. Heartbeat is also a similar case.
What I’m trying to say is that I know about RenderService, but I’m not sure how to get the most precise loop from it. Could you tell me which event would be the most precise to use for a loop?
if your framerate is horrible enough, any loop will break
what you should do is use delta time to sort of “make up” for the lost time
like how when you lag really badly, everything sort of just warps to where its supposed to be once you receive all the delayed info packages before the game goes back to normal
task.wait Is equivalent to RunService.Heartbeat:Wait() which means its tied to the framerate so try adding .001 to task.wait(.001) this should stop it from running each frame (or even higher)
You’re going to have to use a deltatime to solve this.
Psudocode:
(sorry if this is hard to follow, i dont have enough code snippets to create it myself, as it appears .oncooldown controls when the gun can fire, which isn’t controlled by this code snippet)
New frame:
Check time since last frame (deltatime)
Add deltatime to “timepool” variable
If the timepool variable is too high, reset it down to a maximum cap.
Check if the timepool variable is above the theshold:
- if so, fire (or in your case disable.OnCooldown), then reduce the timepool variable by the threshold
This works very well, but I have one question;
How can I make this system harder for hackers to just fire without a cooldown? I will still use this, but if it’s really easy for hackers to just exploit the system, I might not use it.