I am making a wave system and I want my wave to last 20 seconds. The duration starts when a bool value turns true.
The problem is that if the bool changes, the duration will change faster.
local IsBattling = player:WaitForChild("IsBattling")
local duration = 20
IsBattling.Changed:Connect(function(value)
if value == true then
coroutine.wrap(function()
while duration > 0 and IsBattling.Value == true do
duration -= 1
if duration <= 0 then
break
end
task.wait(1)
end
end)()
end
end)
The issue with your current code is that every time the IsBattling value changes, a new coroutine is started, which leads to multiple coroutines running simultaneously and updating the duration value at different rates. Instead, you can modify your code to use a single coroutine that starts when IsBattling becomes true, and stops when it becomes false. Here’s an example:
local IsBattling = player:WaitForChild("IsBattling")
local duration = 20
local waveCoroutine = nil
IsBattling.Changed:Connect(function(value)
if value == true then
waveCoroutine = coroutine.create(function()
while duration > 0 and IsBattling.Value == true do
duration -= 1
task.wait(1)
end
-- Wave ended, reset duration and coroutine
duration = 20
waveCoroutine = nil
end)
coroutine.resume(waveCoroutine)
else
-- Wave ended prematurely, stop the coroutine and reset duration
if waveCoroutine then
coroutine.resume(waveCoroutine, true)
duration = 20
waveCoroutine = nil
end
end
end)
In this updated code, a single coroutine is created when IsBattling becomes true, and it runs until either the duration reaches 0 or IsBattling becomes false. If the wave ends normally, the duration is reset and the coroutine is set to nil . If the wave ends prematurely, the coroutine is stopped, the duration is reset, and the coroutine is set to nil . Note that the coroutine.resume() function is used to start and stop the coroutine. If the coroutine is stopped prematurely, the coroutine.resume() function is called with the second argument set to true , which causes the coroutine to return immediately.