Hey devs, I’m making a timer and want it to be precise, counting time by the millisecond. I could get it to work using wait(), although that would prove to be very inaccurate and the timer wouldn’t be good (as seen in this article) I don’t want to use wait, but use RunService.Heartbeat:Wait() instead. I tried using it but time now goes by way too fast and the timer is still inaccurate. Help? Here is the code I have so far:
The script makes the timer start when a part is touched and stop when another is touched.
local Players = game.Players
local RunService = game:GetService("RunService")
local player = Players.LocalPlayer
local minutes = 0
local seconds = 0
local miliseconds = 0
local stop = false
game.Workspace.Timer.Touched:Connect(function()
wait(.5)
if minutes ~= 0 or seconds ~= 0 or miliseconds ~= 0 then
minutes = 0
seconds = 0
miliseconds = 0
end
repeat
script.Parent.Text = minutes..":"..seconds..":"..miliseconds
miliseconds = miliseconds + 1
if miliseconds == 1000 then
miliseconds = 0
seconds = seconds + 1
end
if seconds == 60 then
seconds = 0
minutes = minutes + 1
end
RunService.Heartbeat:Wait()
until stop == true
end)
game.Workspace.Stop.Touched:Connect(function()
print("Stopped")
stop = true
wait(.1)
stop = false
end)
RunService.Heartbeat fires every frame, meaning if someone has a low frame-rate of 20 it’s only gonna run 20 times a second. You can use tick() instead. See here: Tick() How do I use it?
Alright, using tick is great, but then the loop repeats without a wait and that would obviously make studio crash… How should I go about avoiding that?
I would remove the loop and connect to RunService.Stepped instead:
local RunService = game:GetService("RunService")
local connection = nil
workspace.Timer.Touched:Connect(function()
if (connection) then return end -- already running, do nothing
local startTime = tick()
-- create a connection that will run every frame until
-- connection is disconnected in the stop method
connection = RunService.Stepped:Connect(function()
local elapsed = tick() - startTime
local milliseconds = math.floor(1000 * math.fmod(elapsed, 1))
local seconds = math.floor(elapsed % 60)
local minutes = math.floor(elapsed / 60)
-- prints out every single frame
print(string.format("Elapsed time: %d:%.02d.%.03d", minutes, seconds, milliseconds))
end)
end)
workspace.Stop.Touched:Connect(function()
print("Stopped")
if (connection) then
connection:Disconnect()
connection = nil
end
end)
@nicemike40 Thank you so much. Now I’m trying to display it on the GUI by changing the print statement to script.Parent.Text but that just displays “ELAPSED” on the Ui… I tried to fix it but was never able to without breaking the rest…