There are a lot of ways you can do that, an option would be using os.time
Or creating a timer by yourself.
There are a lot of ways you can do that, an option would be using os.time
Or creating a timer by yourself.
Yes that is another option as well.
The point is, doing wait() manually worse than using tick(), os.time(), or another similar method that’s meant to be used for that, as well as accurately counts the time - free of lag or most problems you could encounter with wait().
Also, it’s not actually waiting for 0.01 seconds to let you know. The fastest you can do with wait() is 0.03, no lower. So it’s not working correctly. I recommend you switch it to an os.time or tick() method instead.
As I stated, it runs perfectly fine on a 0.01 time. I’m not trying to fight.
So, if I were to add to add an if statement to the script it doesn’t work. I stated if player.Started.Value == true then the timer would start but it didn’t.
No it does not. You’re not aware that it’s only running at 0.03 seconds, not 0.01? The limitation of wait() is 0.03, which is about 1/30th of a second.
Take a look for yourself: Decrease the minimum time in wait() to 1/60th of a second
And sorry, I don’t want to be rude at all. I just want to help out to make the solution work.
well, I havent really done time based scripts so I am not used to using tick() or os.time much. So I wouldn’t be able to make it different anyways.
here is a script that will run in the way you wanted it to. It will only give the time if they have started.
local milisecond = 0
local second = 0
local minute = 0
local hour = 0
while wait(0.01) do
if milisecond >= 60 then
milisecond -= 60
second += 1
end
if second >= 60 then
second -= 60
minute += 1
end
if minute >= 60 then
minute -= 60
hour += 1
end
if game.Players.LocalPlayer.Started.Value == true then
milisecond += 1
end
script.Parent.Text = hour..":"..minute..":"..second.."."..milisecond
end
So even though you are defining wait(0.01) its not gonna work at all because the wait() can only go to 0.03 so your script is not gonna work as intended because its gonna run .02 seconds slower than it is meant to. The script may still work because Lua is a forgiving language but your time will always be off. I believe if you change wait to tick() it should fix that problem because the tick() function allows you to start from 0.01.
Sorry! Another question. How would I stop the timer and reset it if a player dies or touches the end part?
it already automatically resets if they die. now if you wanted to reset it, just destroy the gui and replace it.
So to stop it i have to destroy it? Then how would I replace it?
First of all, you’ll want to count the seconds somehow (duh).
I’d recommend marking a start time with os.clock()
Next you’ll want to figure out how to transform this into your timer. The easiest way to do this is using some modulos and some flooring. I like to define all of my time amounts in variables.
Lastly, you’ll want to make sure each piece of the timer except the first is two digits (which is also pretty easy).
You can update the timer at any time, even randomly if you wanted to, and it’ll accurately measure time.
Here’s a full implementation of this (I really recommend trying to understand it, its better to understand the code than to just use it and not have learned anything!):
local RunService = game:GetService("RunService")
local SECOND = 1
local MINUTE = SECOND * 60
local HOUR = MINUTE * 60
local startTime
local function getTime()
return os.clock()
end
local function readableTime(timer)
-- First of all, get all of the times in their amounts
local remainder = timer -- Basically this is the "not included" time
local hours = math.floor(remainder / HOUR) -- Figure out the number of whole hours
remainder = timer % HOUR -- Update our remainder time
local minutes = math.floor(remainder / MINUTE) -- Figure out the number of whole minutes in the remaining time
remainder = remainder % MINUTE -- Update our remainder time again
local seconds = math.floor(remainder / SECOND) -- Figure out the number of whole seconds in the remaining time
remainder = timer % SECOND
local hundredthsOfASecond = math.floor(remainder * 10^2) / 10^2 -- Take the first two decimal digits
minutes = tostring(minutes)
if #minutes < 2 then -- Make sure the minutes section is two digits, if not, its less than 10, so we can add a 0
minutes = "0"..minutes
end
seconds = tostring(seconds)
if #seconds < 2 then -- Make sure the seconds section is two digits, if not, its less than 10, so we can add a 0
seconds = "0"..seconds
end
hundredthsOfASecond = tostring(hundredthsOfASecond):sub(2) -- Convert the decimal results to a string and remove the first 0
return table.concat({hours, minutes, seconds..hundredthsOfASecond}, ":") -- Concatenate everything with a : in between
end
local function updateTimer()
local currentTime = getTime()
local timer = currentTime - startTime
local timerText = readableTime(timer)
-- Set the timer text
end
local function startTimer() -- Start the timer!
local currentTime = getTime()
if startTime ~= currentTime then
startTime = currentTime
coroutine.wrap(function() -- Create a new thread for the timer to run in
local timerTime = startTime
while timerTime == startTime do -- Make sure the current timer is running
updateTimer()
RunService.Heartbeat:Wait() -- Wait for Heartbeat (Approximately 1/60th of a second)
end
end)()
end
end
local function stopTimer() -- Stop the timer
startTime = 0 -- This causes other timer loops to exit since the timer will check if it has been changed and exit if it has
end
startTimer()
-- Other code
So you recommend me using a module?
Well, I mean, its up to you how you do it. I’ve simply provided an explanation for how you can accurately track the time that has passed and create a readable time from that (e.g. 1:02:03.28
).
You can implement it in its own module, and maybe even make a Timer object so you can use more than one timer at once, or you can use it in its own unique script.
Hmm is it ok to implement this sort of code into a local script? Because I want it to time the player when doing the obby with a gui.
Mhm! It honestly makes sense to me to only include the timer code in local scripts since updating a property like that would replicate each time. If ever you needed to synchronize other player’s timers, you could just send the start time to the client.
You would need to translate the server’s time into the client’s time though, which you could do in a few ways, the easiest of which is just to have the server send the os.clock()
result to the client once, and the client can compare its own os.clock()
value:
local serverClockTime = getServerClockTimeSomehow()
local clientClockTime = os.clock()
local clockTimeOffset = serverClockTime - clientClockTime
function getTime()
return clockTimeOffset + os.clock()
end
That’s certainly not perfect but the most you’ll end up with is players seeing a slightly delayed timer. You could resynchronize the clocks occasionally if you wanted to, and you can get even more complicated and average a couple of the previous values together when you do that, but, that’s really only if you care.
Another option if you want complete accuracy in a much easier way is to use os.time()
rather than os.clock()
since it should be synchronized between the client and the server, whereas os.clock()
is not synchronized (its the newly added version of tick
essentially). The downside to this is you lose out on decimal seconds, but, if you don’t care about this, you don’t care about it.
Hello! So I created a new script, with tick. This is the script, but I don’t know how to make a condition before running the script and how to stop the timer and reset it. Any suggestions? Here is the script…
local start = tick()
while true do
wait()
local diff = tick() - start
local min = math.floor(diff / 60)
local sec = diff - min*60
local mil = math.floor((sec - math.floor(sec)) * 10)
sec = math.floor(sec)
script.Parent.Text = min..":"..sec..":"..mil
end
Well, you can use a function to start the timer. To stop the timer you can just have some condition in the loop, and, you can have a function which causes the timer to stop by changing something. The way I did it in my example script above is by basically seeing if start was still the same, so, if you started a new timer, it’d exit the loop since the start time was different, that way multiple timers wouldn’t run at once. And then to make the timer exit, I just change the start time to 0.
And as you can see in my example code, the way I made the timer run without blocking other code is by putting it in a new thread.
I’d also recommend using os.clock
now instead of tick
(os.clock
is a new function which does almost the same thing, but, when it was implemented Roblox suggested no longer using tick, I’d assume either for performance reasons, or something else)
So, should I just replace the tick statements with os.clock?