So this is just a question I have been trying to deal with. Is there any way I can make the loop wait until either one of the 2 events (value.Changed or MoveToFinished) happen so it can check to break the loop?
Right now the code just waits until the humanoid.MoveToFinished happens, but I want to make it continue the loop on another event at the same time.
for i, waypoint in pairs(path:GetWaypoints()) do
if activeID ~= currentID then break end
hum:MoveTo(waypoint.Position)
hum.MoveToFinished:Wait() -- or workspace.Value.Changed:Wait()?
end
The script I have (without workspace.Value.Changed) works fine, itās just that it seems pretty unoptimized since this is running every runservice.Stepped leaving many loops not broken and still waiting until it triggers randomly (iāve tested it with a print when the loop breaks, when it does it prints like 56x the message at once, sometimes more, depends on how often the dummy goes through the spots it has walked through already. Simply itās not consistent, doesnt stop right after the activeID changes.), which makes me worry a little and leaves me unsatisfied with it.
function waitForChange()
local value1Changed = false
local value2Changed = false
local function checkValue1()
value1Changed = true
end
local function checkValue2()
value2Changed = true
end
workspace.Value.Changed:Connect(checkValue1)
hum.MoveToFinished:Connect(checkValue2)
repeat
wait()
until value1Changed or value2Changed
return
end
--[[
waitForChange()
print("Value changed")
]]
Basically, you call the function and it waits for a change and moves on once there is a change.
You could make a BindableEvent that you fire from both signals and wait on:
for i, waypoint in pairs(path:GetWaypoints()) do
if activeID ~= currentID then break end
local combinedSignal = Instance.new("BindableEvent")
hum.MoveToFinished::Connect(function() combinedSignal:Fire("MoveToFinished") end)
workspace.Value.Changed:Connect(function() combinedSignal:Fire("ValueChanged") end)
hum:MoveTo(waypoint.Position)
local whichSignal = combinedSignal.Event:Wait()
if whichSignal == "MoveToFinished" then
-- handle move to finished
else
-- handle value changed
end
end
I didnāt test it but that would be the gist of it.
You can make it more complicated if you need things like forwarding the individual eventās arguments to the combined event.
Thank you, this worked just right! I havenāt ever read up on bindable events so this was a nice thing to learn, might use it in future scripts too.
I just polished it up a little, Iāll leave the code for any future devs to see.
local val = instance.new("StringValue")
local activeID
-- keep in mind this runs every runservice.Stepped from now, this is not the full script
activeID = newproxy()
val.Value = tostring(activeID) -- triggers val.Changed on previous loops and breaks them
local currentID = activeID
for i, waypoint in pairs(path:GetWaypoints()) do
if activeID ~= currentID then break end
if i == 1 then
else
hum:MoveTo(waypoint.Position)
local combinedSignal = Instance.new("BindableEvent")
local conn1 = hum.MoveToFinished:Once(function() combinedSignal:Fire() end)
local conn2 = val.Changed:Once(function() combinedSignal:Fire() end) --Can also send in arguments for extra steps,
combinedSignal.Event:Wait() --and get them in a variable here!
conn1:Disconnect()
conn2:Disconnect()
combinedSignal:Destroy()
end
end
print("completed path")
Now ācompleted pathā prints consistently (2-5x at once), just as youād expect. The dummy seems to be moving cleaner? as well.
Hope the instance.new and making connections every .Stepped wont make server performance too bad or something, dunno how those things work. Seems perfectly fine after testing a little though. I can finally rest at peace.