Hello, I am using the MoveTo function on the humanoid and I do not want to connect the MoveToFinished event, instead I want to yield it until it fires. I was wondering if how should I make a timeout or a way to cancel the yield if it has been yielding over 2 seconds for situations that the humanoid maybe walking towards a wall?
humanoid.MoveToFinished:Wait();
I’ve tried using:
local moveToFinished = false; local moveToTimeout = tick();
spawn(function() humanoid.MoveToFinished:Wait(); moveToFinished = true; end);
repeat until moveToFinished or (tick()-moveToTimeout > 1) or not wait(1/60);
But I find this code rather inefficient, I don’t really want a loop running on the script.
This post may be of interest to you. You can probably customize it to fit your needs (ie, have it return true if it finishes successfully or false if it doesn’t or if it times out).
-- Happens before the event
local bindable = Instance.new("BindableEvent")
local waiting = true
delay(timeout, function ()
if waiting then bindable:Fire() end
end)
local connection = event:Connect(function ()
if waiting then bindable:Fire() end
end)
bindable.Event:Wait()
bindable:Destroy()
connection:Disconnect()
-- Happens after the event
Consider using a pool of bindables to make this more efficient. This would be a lot cleaner if threads weren’t automatically scheduled when yielded and thus we could use the yield method of the coroutine library.
Personally, I would implement it as follows.
-- Happens before the event
local function afterTheEvent()
-- Happens after the event
end
local connection
delay(timeout, function ()
if connection.IsConnected then
connection:Disconnect()
afterTheEvent()
end
end)
connection = event:Connect(function ()
connection:Disconnect()
afterTheEvent()
end)
If you’re already using an event, you can simply just hook up to the event as well, instead of making a new BindableEvent.
See the samples below.
local continue = false
local con = humanoid.MoveToFinished:Connect(function()
continue = true
end)
delay(3, function() continue = true end)
repeat wait() until continue
local continue = false
local start = tick()
local con = humanoid.MoveToFinished:Connect(function()
continue = true
end)
repeat wait() until continue or (tick()-start >= 3)
Don’t you get the same situation when using Event:Wait() though? The thread yields for the same amount of time.
Is Event:Wait() less taxing than a loop waiting for the variable because it happens on a lower level, then?
You’ll actually find that yours should yield for a slightly longer duration. With your implementation, the threads yield until the scheduler resumes them, while mine are resumed by the events themselves. The following example demonstrates this subtle delay:
local t
local continue = false
local con = humanoid.MoveToFinished:Connect(function()
continue = true
t = tick()
end)
delay(3, function()
continue = true
t = tick()
end)
repeat wait() until continue
print(tick() - t)
Lower-level may not be the correct term, but essentially my implementation is less-taxing since it does not poll a variable (continue) as it will be resumed automatically when the event occurs (or the timeout).