Have you ever wanted to do something like this?
local hit = part.Touched:Wait(5) -- With 5 being the time until timeout (like :WaitForChild(5))
if hit then
-- Something touched part within the 5 seconds!
else
-- Nothing touched part
end
Well now you can!
(but not with that simple syntax )
local function WaitUntil(event, timeout)
local timedOut = Instance.new("BindableEvent") -- This is used to return whether or not the event listening has timed out (while also yielding it with a timedOut.Event:Wait())
local result = nil -- This will be a tuple of what arguments the callback function receives. For ex. local hit = part.Touched:Wait() with "result" being "hit"
local function fireTimedOut(bool) -- "bool" here represents whether or not we timed out
timedOut:Fire(bool) -- As soon as this happens, the script will return: timedOut (as "bool") and "result" (tuple of passed args to callback function)
timedOut:Destroy() -- Cleanup
end
local eventConn; eventConn = event:Connect(function(...)
eventConn:Disconnect() -- Disconnect the event immediately so we don't do anything if it fires again (we are only listening for 1 happening because of :Wait())
result = {...} -- Set the result to the passed args from the event firing
fireTimedOut(false) -- We are now ready to return: false, unpack(result)
end)
task.delay(timeout, function()
if eventConn.Connected then -- If the event is still connected, that means it didn't fire within the "timeout" duration; therefore, we timed out
eventConn:Disconnect() -- Same reason as above
fireTimedOut(true) -- Same reason as above, but now we're returning timedOut as true
end
end)
return timedOut.Event:Wait(), unpack(result or {}) -- Keep in mind here that it's important the timedOut.Event:Wait() is first or else the result tuple will always be nil
end
-- Example usage
local part = Instance.new("Part")
part.Position += Vector3.new(0, 5, 0)
part.Anchored = true
part.Parent = workspace
local s = os.clock()
local timedOut, hit = WaitUntil(part.Touched, 5)
if not timedOut then
print("part.Touched:Wait() returned", hit) -- This is basically what has happened
else
print("part.Touched:Wait() timed out after", os.clock() - s, "seconds") -- ^^^
end
If you have any questions or concerns please let me know by replying to this post, thanks!