Yeah, that’s pretty much how you do it. You let all of the events “check in” and do the action when the last of them completes.
I’m puzzled why you need this for tweens in particular, though.
If it’s certain that the tweens will always end at the same time, then just wait for only one of them.
If you know from the durations which tween will end later, just wait for the later tween.
If that’s too complicated (it can get complicated), then yes, go ahead and wait for both of them.
I also have to note that if you :Connect()
to a tween, then the connection stays live after the tween is done. It won’t fire again if you just forget/never use that same tween instance again, but it’s something to keep in mind, especially if you do this to e.g. Touched
events, which can and will run again immediately afterward.
So you’ll want to somehow disconnect the connections afterward, either by keeping the connections and disconnecting them as they fire, or using :Wait()
to run only once (but stop the current thread/script).
Putting this here because I already wrote it so why not
This one waits for each event inline, without forcing you to continue all your stuff in a function:
local thisthread = coroutine.running()
local function action()
coroutine.resume(thisthread)
end
tween1.Completed:Connect(action)
tween2.Completed:Connect(action)
coroutine.yield()
coroutine.yield()
--do whatever happens when both events fire
(coroutine.yield()
will pause this thread like task.wait()
or any other async function do, except it will only wake when it is coroutine.resume()
d, which is what the tweens will do)
This function just lets you wait for a list of connections:
local function waiter(signal, coro)
signal:Wait()
return coroutine.resume(coro)
end
local function waitForAll(...)
local signals = {...}
local this = coroutine.running()
for signal in ipairs(signals) do
coroutine.wrap(waiter)(signal, this)
end
for i = 1, #signals do
coroutine.yield()
end
end
waitForAll(tween1.Completed, tween2.Completed)
--do whatever happens when both events fire
waitForAll(workspace.Part1.Touched, workspace.Part2.Touched, workspace.Part3.Touched)
-- if you want this but even better, use Promises