Hi! I’m here to announce the creation of EzTimer! A fool-proof module that enables you to create timers and stopwatches with ease! But that’s not all. I’ve also made a handy-dandy plugin to go with it, that makes timer creation a breeze!
Module Information
How to use
Installation
To use this brilliant module, get it here:
Then insert it into studio and put it in ReplicatedStorage.
Then add a LocalScript and put it in StarterGui (The module can be used on the server) and type:
local EzTimer = require(game:GetService('ReplicatedStorage'):WaitForChild('EzTimer'))
Timers
How to make timers
Creating a timer
To create a timer, simply type
local timer = EzTimer:Create('Timer') -- You can name the timer whatever you want
Setting Parameters
To set the timer’s parameters, you must first create a dictionary containing the parameters you want like this:
local timerParameters = {
Start = 10,
IntervalDuration = 1,
Separator = ':',
Separators = 0,
Countdown = true,
Target = 0
}
Explanation of parameters
Parameters Eplained
Here’s an explanation of all the Timer Parameters
Start (number)
This is what the timer will start at.
IntervalDuration
This is how long the timer will between seconds. If IntervalDuration
was equal to 2 and the Start
was equal to 0, the timer would start at 0, wait 2 seconds, then move to 1.
Separator (string)
When Separators
is more than 0, this is what will separate the seconds, minutes and hours in the timer’s UI, for example, if Separators is set to 2 and the Separator is set to : then the timer will looks like this: 00:00:00 (the first set of zeros showing the hours, the second set showing the minutes, and the third showing the seconds. If Separators is set to 1 and Separator is set to " , the timer will look like this: 00"00 (the first set of zeros showing the minutes and the second set showing the seconds.
Separators (number)
When Separators
is equal to 1, the timer will split the time into minutes and seconds, when equal to 2, the timer will split the time into hours, minutes and seconds, and so on. When Separators
is equal to 0, the timer will not split the time at all and it will show the remaining time in seconds.
Countdown (boolean)
When Countdown
is equal to true
, the timer will count down from Start
, when false, the timer will count up from Start
Target (number)
When the timer reaches this number, it will stop.
Then set the parameters by using the SetParams()
function like so:
timer:SetParams(timerParameters)
If something is wrong with the parameters, the timer’s parameters will not be set and the module will tell you what is wrong with them.
Setting the UI
To set the UI Element that will show where the timer is at, you’ll need to use the SetUI()
function like this:
Timer:SetUI(UIElement) --Make sure the UI Element has a text property
If you want multiple UI Elements to show where the timer is at, just change UIElement
to an array containing all the UI Elements you want like this:
local Elements = {Element1,Element2,Element3}
Timer:SetUI(Elements)
If you want a UIElement to show where the timer is when the timer has already started, use the ShowTimeOn()
function like this:
Timer:ShowTimeOn(Element)
The timer will show the time on the UIElement at the next tick.
Setting the tick sound
(This step is optional)
If you want the timer to make a sound whenever the time left changes, use the SetSound()
function like this:
timer:SetSound(SoundId)
Starting the timer
After you have set the parameters, to start the timer, use the Start()
function.
timer:Start()
(If parameters have not been set, the timer will use these parameters instead:)
Start = 60
IntervalDuration = 1
Separator = ':'
Separators = 1
Countdown = true
Target = 0
Pausing the timer
If you’re following allong with the tutorial, your code should look like this:
local EzTimer = require(game:GetService('ReplicatedStorage'):WaitForChild('EzTimer'))
local timer = EzTimer:Create('Timer')
local timerParameters = {
Start = 10,
IntervalDuration = 1,
Separator = ':',
Separators = 0,
Countdown = true,
Target = 0
}
timer:SetParams(timerParameters)
timer:Start()
At this point, the timer should already be running. If you want to pause the timer before it’s finished, use the Pause()
functions like this:
timer:Pause()
If the timer isn’t running, nothing will happen.
To resume the timer, use the Resume()
function like this:
timer:Resume()
If the timer isn’t paused, nothing will happen.
Getting the status of the timer
If you want to get the status of the timer, use the GetStatus()
function like this:
Timer:GetStatus()
Statuses Explained
Idle
- The timer is not in use and hasn’t been started
Running
- The timer has been started and is currently in use
Paused
- The timer is not currently in use and has been paused
Events
Here are all the events of the timer
Finished
This event is fired when the timer has reached it’s target. To detect when the timer has finished in a script write this:
timer.Finished:Connect()
Paused
This event is fired when the timer has been paused. To detect when the timer has finished in a script write this:
timer.Paused:Connect()
Started
This event is fired when the timer has started. To detect when this happens, write this:
timer.Began:Connect()
Stopwatches
With this module, you can also make stopwatches
How to make a stopwatch
To create a stopwatch, use the ```CreateStopwatch() function like this:
local stopwatch = EzTimer:CreateStopwatch(Name)
Starting the stopwatch
To start the stopwatch, type:
stopwatch:Start(UIElement,Separator,StartTime)
Arguements Explained
UIElement
- The UI Element that will show the time on the stopwatch. This must have a text property
Separator
- This is what will separate the hours, minutes, seconds and milliseconds on the stopwatch. This must be a string
StartTime
- This parameter is not neccesary for stopwatches. When provided, the watch will show how much time has past since this time. If not provided, the watch will show how much time has passed since the time it was started. When providing StartTime
, use tick()
Stopping the stopwatch
To stop the stopwatch, use the Stop()
function like this:
stopwatch:Stop()
If you want the time between when the stopwatch started and when it stopped, make the Stop()
function a variable like this:
local endTime = stopwatch:Stop()
Plugin Information
A full tutorial and explanation of the EzTimer Creator can be found here.
Module Source Code
local funcs = {}
local RunService = game:GetService('RunService')
funcs.__index = funcs
local timers = {}
local watches = {}
local deafultParams = {
Start = 60,
IntervalDuration = 1,
Separator = ':',
Separators = 1,
Countdown = false,
Target = 0
}
function funcs:Create(Name)
local finishedEvent = Instance.new('BindableEvent')
local pausedEvent = Instance.new('BindableEvent')
if Name then
timers[Name] = {
Parameters = { Start = 0,
IntervalDuration = 0,
Separator = ':',
Separators = 0,
Countdown = false,
Target = 0},
Status = 'Idle',
UI = nil,
Current = 0,
Sound = '',
Start = os.time(),
Paused = pausedEvent.Event,
Finished = finishedEvent.Event,
StartTimer = Instance.new('BindableEvent')
}
local new = {}
--Timer Parameters
new['Parameters'] = {
Start = 60,
IntervalDuration = 1,
Separator = ':',
Separators = 0,
Countdown = true,
Target = 0}
new['Status'] = 'Idle'
new['UI'] = nil
new['Current'] = 0
new['IntervalDuration'] = 0
new['Sound'] = ''
new['StartTime'] = math.floor(os.time())
new['Paused'] = pausedEvent.Event
new['Finished'] = finishedEvent.Event
-- Timer functions
function new:Start(Timer)
local timer = new
if timer then
if not timer.UI then
warn('Timer "'.. Timer .. '" has no UI')
end
local params = timer.Parameters
timer.Status = 'Running'
timer.Current = timer.Parameters.Start
coroutine.wrap(function()
repeat
if params.Separators == 0 then
if timer.Parameters.Countdown == true then
timer.Current = timer.Current - 1
else
timer.Current = timer.Current + 1
end
if timer.UI then
timer.UI.Text = timer.Current
end
wait(timer.Parameters.IntervalDuration)
end
if params.Separators == 1 then
if params.Countdown == true then
timer.Current = timer.Current - 1
local show = ''
local secs = timer.Current % 60
local mins = math.floor(timer.Current/60)
if string.len(secs) == 1 then
secs = '0'.. secs
end
if string.len(mins) == 1 then
mins = '0'.. mins
end
show = mins .. params.Separator .. secs
timer.UI.Text = show
wait(timer.Parameters.IntervalDuration)
else
timer.Current = timer.Current + 1
local show = ''
local secs = timer.Current % 60
local mins = math.floor(timer.Current/60)
if string.len(secs) == 1 then
secs = '0'.. secs
end
if string.len(mins) == 1 then
mins = '0'.. mins
end
show = mins .. params.Separator .. secs
if new.Sound ~= '' then
local sound = Instance.new('Sound')
sound.Parent = game:GetService('SoundService')
sound.Name = 'Tick'
sound.SoundId = new.Sound
sound:Play()
sound.Ended:Connect(function()
sound:Destroy()
end)
end
timer.UI.Text = show
wait(timer.Parameters.IntervalDuration)
end
end
if params.Separators == 2 then
if params.Countdown == true then
timer.Current = timer.Current - 1
local show = ''
local secs = timer.Current % 60
local mins = math.floor(timer.Current / 60)
local hrs = math.floor(timer.Current/3600)
if mins > 59 then
repeat mins = mins - 60
until mins < 60
end
if string.len(secs) == 1 then
secs = '0'.. secs
end
if string.len(mins) == 1 then
mins = '0'.. mins
end
if string.len(hrs) == 1 then
hrs = '0'.. hrs
end
show = hrs.. params.Separator .. mins.. params.Separator .. secs
timer.UI.Text = show
wait(timer.Parameters.IntervalDuration)
end
end
until
timer.Current == timer.Parameters.Target or timer.Status == 'Paused'
if timer.Current == timer.Parameters.Target then
finishedEvent:Fire()
else
pausedEvent:Fire()
end
end)()
else
warn('Timer '.. Timer .. ' not found')
end
end
timers[Name].StartTimer.Event:Connect(function()
new:Start()
end)
function new:SetParams(TimerParams)
if TimerParams then
local valid = true
local start = TimerParams.Start
local interval = TimerParams.IntervalDuration
local separator = TimerParams.Separator
local separators = TimerParams.Separators
local countdown = TimerParams.Countdown
local target = TimerParams.Target
if start then
if type(start) ~= 'number' then
warn('Start must be a number')
valid = false
end
else
TimerParams.Start = deafultParams.Start
warn('Start not specified')
end
if interval then
if type(interval) ~= 'number' then
warn('IntervalDuration must be a number')
valid = false
end
else
TimerParams.IntervalDuration = deafultParams.IntervalDuration
warn('IntervalDuration not specified')
end
if separator then
if type(separator) ~= 'string' then
warn('Separator must be a string')
valid = false
end
else
TimerParams.Target = deafultParams.Target
warn('Separator not specified')
TimerParams.Separator = deafultParams.Separator
end
if separators then
if type(separators) ~= 'number' then
warn('Separators must be a number')
valid = false
else
if separators < 0 or separators > 2 then
warn('There can only between 0 to 2 separators')
valid = false
end
end
else
TimerParams.Separators = deafultParams.Separators
warn('Separators not specified')
end
if countdown then
if type(countdown) ~= 'boolean' then
warn('Countdown must be a boolean')
valid = false
end
else
TimerParams.Countdown = deafultParams.Countdown
warn('Countdown not specified')
end
if target then
if type(target) ~= 'number' then
warn('Target must be a number')
valid = false
end
else
TimerParams.Target = deafultParams.Target
warn('Target not specified')
end
if valid == true then
timers[Name].Parameters = TimerParams
new.Parameters = TimerParams
end
else
warn('TimerParams not specified')
end
end
function new:Pause()
if new.Status == 'Running' then
new.Status = 'Paused'
else
warn('Timer "'.. Name .. '" is not running; did not pause')
end
end
function new:Resume()
if new.Status == 'Paused' then
new.Status = 'Running'
new:SetParams({
Start = new.Current,
IntervalDuration = new.Parameters.IntervalDuration,
Separator = new.Parameters.Separator,
Separators = new.Parameters.Separators,
Countdown = new.Parameters.Countdown,
Target = new.Parameters.Target})
new:Start()
else
warn('Timer "'.. Name .. '" is not paused; did not resume')
end
end
function new:SetUI(Element)
local success,errorMessage = pcall(function()
Element.Text = ''
end)
if success then
new.UI = Element
else
warn('UI Element "'.. Element .. '" does not have a Text property')
end
end
function new:SetSound(SoundID)
local MarketplaceService = game:GetService'MarketplaceService'
local Success, Response = pcall(MarketplaceService.GetProductInfo, MarketplaceService, SoundID)
if Success then
if Response.AssetTypeId == Enum.AssetType.Audio.Value then
new.Sound = 'rbxassetid://' .. SoundID
else
warn(SoundID .. ' is not a sound ID')
end
else
warn(SoundID .. ' not found')
end
end
function new:GetStatus()
return new.Status
end
return new
else
warn('No name specified for timer')
end
end
function funcs:CreateStopWatch(Name)
if Name then
local watch = {}
local stopEvent = Instance.new('BindableEvent')
watch['Stopped'] = stopEvent.Event
watch['Status'] = 'Idle'
watch['Begin'] = 0
function watch:Start(UI,Separator,StartTime)
if not UI then
warn('UI not specified')
end
local start = tick()
watch.Begin = start
local stop = false
local sep = Separator
if not Separator then
sep = ':'
end
if StartTime then
start = StartTime
end
coroutine.wrap(function()
repeat
local diff = tick() - start
local min = math.floor(diff / 60)
local hr = math.floor(diff / 3600)
local sec = diff - min*60
local mil = math.floor((sec - math.floor(sec)) * 100)
sec = math.floor(sec)
if string.len(min) == 1 then
if min ~= 0 then
min = '0'.. min
end
end
if string.len(sec) == 1 then
sec = '0'.. sec
end
if mil == 0 then
mil = '00'
end
if min == 0 then
UI.Text = sec .. sep .. mil
else
if hr == 0 then
UI.Text = min.. sep.. sec.. sep.. mil
else
UI.Text = hr.. sep.. min.. sep.. sec..sep ..mil ..sep
end
end
watches[Name] = watch
RunService.Heartbeat:Wait()
until watch.Status == 'Stopped'
end)()
end
function watch:Stop()
watch.Status = 'Stopped'
stopEvent:Fire()
return tick() - watch.Begin
end
watches[Name] = watch
return watch
else
warn('No name provided for stop watch')
end
end
function funcs:GetTimers()
local TIMERS = {}
for i,v in pairs(timers) do
TIMERS[i] = {
Start = v.Start,
IntervalDuration = v.IntervalDuration,
Separator = v.Separator,
Separators = v.Separators,
Countdown = v.Countdown,
Target = v.Target}
end
return TIMERS
end
function funcs:Start(Name)
if Name then
if timers[Name] then
timers[Name].StartTimer:Fire()
end
else
warn('No name provided')
end
end
return funcs
Hope you can put this module to good use!