I’m stuck at a timer script, not just stuck but I got no idea on how to do what I want
So basically I wanted to do something like this:
make a tower defense game timer where it shows how many seconds left until next round
However, I cannot just make a normal timer with for loop. I need the timer to stop counting ONCE an event is fired ( skip wave event ), once the event is fired it starts counting again from a new value, kind of like abandoning the old timer.
I have no idea how to this, and also once the timer finished counting it returns. Do I use “coroutines?” or "events?"If so, how do I do this?
local fired = false
local timeLeft = 60
-- setup your connection BEFORE the loop
event.OnServer/ClientEvent:Connect(function()
fired = true
end)
while true do
wait(1) -- your delay time/loop choice
timeLeft-- -- take away 1 from the time left
if fired then
-- feel free to assign a variable and disconnect the event
timeLeft = 60
fired = false
elseif timeLeft <= 0 then
-- run your code if the timer is out
end
end
I don’t think that method changes any variables, it just checks a pre-existing one.
warning: the code might have some slight issues/places where you need to edit, but it should lead you in the right direction
--countdown timer, gets a numbervalue asset and decreases it until either the timer is 0 or destroyed
local function CountdownTimer(timerAsset: NumberValue)
task.spawn(function()
repeat
task.wait(1)
timerAsset.Value = math.max(0, timerAsset.Value - 1)
until
(timerAsset == nil or timerAsset == 0)
game.Debris:AddItem(timerAsset, 3)
end)
end
--create a new timer for an object at a given path
local function NewTimer(path, startValue: number)
if not path then
warn("Must pass path for new timer's location.")
return
end
if path:FindFirstChild("Timer") then
warn("Path already has a timer. Cannot have 2 timers for the same object.")
return
end
local timer = Instance.new("NumberValue")
timer.Name = "Timer"
timer.Value = startValue or 0
timer.Parent = path
CountdownTimer(timer)
return timer
end
--convert timer to XX:XX string representation
local function ConvertTimerToString(timeValue: NumberValue)
local min = math.floor(timeValue.Value / 60)
local sec = timeValue.Value - min*60
local timeText
if min < 10 then
timeText = "0" .. tostring(min)
else
timeText = tostring(min)
end
if sec < 10 then
timeText = timeText .. ":0" .. tostring(sec)
else
timeText = timeText .. ":" .. tostring(sec)
end
return timeText
end
It is a timer in a tower defense game where the timer is running and it has to be stopped suddenly when someone skips the wave or every single enemy is dead.
The point is I don’t know how to suddenly stop a running function and start a new one.
for example I changed the fired suddenly when someone skips the wave, if it’s that script then it will have to wait 1 second before doing something else. I don’t want that 1 second delay as it may affect other scripts’ timing and stuff.
Are you wanting to do something else inside the single script or on other scripts? If it’s inside that script, then you can use task.spawn(), if it’s for other scripts, I don’t think wait() effects scripts other than the one calling it.
ye but how do I stop the function suddenly anytime after task.spawn(), I know methods like doing checks inside the loop but the loop loops every 1 second and I don’t want a 1 second delay before checking
You can use task.cancel() to stop it, or simply break your loop when the condition is met and that will result in the thread of task.spawn() hitting the end of its stack. But that’s a fix to be used later.
Edit: Use the break method for now since task.cancel() is still unreleased. (Forgot it was still unreleased)
I didn’t read through comments but I’ll just say this:
local RepS = game:GetService("ReplicatedStorage")
local NWT = RepS.NextWaveTime
local CT = RepS.CurrentTime
local Displaying = true
NWT.Changed:Connect(function()
Displaying = false
print("NEW EVENT")
wait(1)
Displaying = true
end)
while wait(0.4) do -- 0.4 seconds so it runs at least 2x per update. do maybe 0.9 so it checks at least once per update.
local t = NWT.Value - CT.Value
if t<0 then t = 0 end
t = math.ceil(t)
if Displaying then
print(t)
end
end
where NextWaveTime is a NumberValue representing when the next wave will come, and CurrentTime is a NumberValue representing the relative current time.