local function round()
while true do
print("Still going!")
if roundTime.Value > 0 then
roundTime.Value -= 1
else
res.Value = "Time ran out."
end
wait(1)
end
end
local thread = coroutine.create(round)
start.Event:Connect(function()
ended = false
coroutine.resume(thread)
end)
res:GetPropertyChangedSignal("Value"):Connect(function()
if res.Value ~= nil or res.Value ~= "" then
print("Result changed, pausing...")
ended = true
ss:WaitForChild("Events"):WaitForChild("RoundResults"):Fire(res.Value, winners)
coroutine.yield(thread)
thread = coroutine.create(round)
coroutine.yield(thread)
end
end)
Context:
The event is only being fired once, but the coroutine’s still going. The “still going” prints even after the “result changed” prints. Why is it still going, and how can I stop it?
I am pretty sure you can only pause a coroutine from inside the coroutine.
You can make a variable called “paused”, and make that when it’s true, you do coroutine.yield() within the thread (function).
Something like this:
local paused = false --Variable that'll determine the yield
local function round()
while true do
if paused then coroutine.yield() end --Yield if pause is true
print("Still going!")
if roundTime.Value > 0 then
roundTime.Value -= 1
else
res.Value = "Time ran out."
end
wait(1)
end
end
local thread = coroutine.create(round)
start.Event:Connect(function()
ended = false
coroutine.resume(thread)
paused = false
end)
res:GetPropertyChangedSignal("Value"):Connect(function()
if res.Value ~= nil or res.Value ~= "" then
print("Result changed, pausing...")
ended = true
paused = true --Make the coroutine yield from insidess:WaitForChild("Events"):WaitForChild("RoundResults"):Fire(res.Value, winners)
thread = coroutine.create(round)
--the coroutine is yielded from inside as the variable is still true.
end
end)
There’s just one problem to that - it destroys the entire reason I used coroutines. I wanted the while true loop to instantly stop when the ended variable is set to true. (or just when the last part runs)
I made a module that eliminates this problem. You call wait() and it will wait until either the time you specified is up, or a condition is met. Here is the module.
local module = {}
function module.new()
local self = setmetatable({},{__index=module})
self.bypassWaits = false
self.debug = false
return self
end
function module:wait(amount,...)
if amount > 0 then
local waitEndsAt = os.clock()+amount
local waitResult = "Waiting"
while waitEndsAt > os.clock() do
game:GetService("RunService").Heartbeat:Wait()
local breakWait = false
if self.bypassWaits then
breakWait = true
end
for _,v in pairs({...}) do
if v[1] == v[2] then
breakWait = true
break
end
end
if breakWait then
break
end
end
if waitEndsAt > os.clock() then
waitResult = "Timed Out"
else
waitResult = "Conditional Override"
end
return waitResult
end
end
return module
To apply this to your code, and make it stop as instant as possible, just change your “wait(1)” to “module.new():wait(1,{paused,true})” The module interprets this line as "Wait until 1 second has elapsed, OR until the variable paused is set to true.