Is there a way to cancel `Humanoid.MoveToFinished:Wait()` in a loop?

I think you could change that out for a repeat block.

repeat wait() until (stopMoving or OtherCondition)

Still not exactly sure what you need, as my comprehension is poor. But, from my understanding, this should fix your issue.

I got an idea from that thank you! I will let you know If I manage to fix it :slight_smile:

1 Like

You can’t ever cancel RBXScriptSignal:Wait() as it yields until the signal fires and obviously developer code is unable to fire such signals.

I see thank you very much but I think instead of something that yields such as a event:Wait() I’d use a different approach like repeat wait() as I can definitely check for conditions like so.

Welp I came up with something but unfortunately it didn’t work as well, it seems as if it was glitching even more :laughing:. Thanks for trying to help though

I’d suggest against using repeat wait() until true for the fact that it’s inefficient. Event based programming is almost always favourable.

What you could do, is each time you call MoveToFinished:Wait(), assign a variable such as "moveId’. This way, if you had multiple MoveToFinished events yielding, you could check that the current moveId is equal to the latest moveId. Here’s an example

local latestMoveId
local function Move(to)
    local thisMoveId = elapsedTime() -- you can use anything as an ID, I like to use elapsedTime() as it guarantees no duplicates in this session (tick() would produce the same desired result)
    latestMoveId = thisMoveId
    humanoid:MoveTo(to)
    humanoid.MoveToFinished:Wait()
    if latestMoveId == thisMoveId then
        -- this will only run on the most 'up to date' MoveToFinished event.
    end
end

This will still cause the events to stack up, using more memory (likely not notable unless you were calling Move a LOT), however it will ensure only the latest Move() call will run beyond the MoveToFinished event!

I’ve having a little trouble understanding here, could you tell me what happens if latestMoveId == thisMoveId then? I don’t see actually solving the problem either because again the statement will run after the humanoid finishes moving to a point since it yields and we will still have to wait.

Oh, perhaps I misunderstood the question here. My example would solve the problem of stacking up :MoveTo/.MoveToFinished events, but I think your issue is different, my mistake.

Are you able to provide a place file where we could replicate this problem? It would be a lot of help if we could experiment with it!

Would you like to contact me via Discord? I can provide details there

Discord: Mystifine#4924

You could skip using humanoid.MoveToFinished:Wait() all together. Create your own condition for finishing the move and that would allow you to break wait loop however you like. When I wrote my NPC AI I used MoveTo with my pathfinding functions and found the MoveToFinished caused me problems. I simply wrote a check to detect when the NPC got close enough to the position and ended the MoveTo or switched to MoveTo a different position. Could be an option for you to do it this way.

I did happen to do so like so:

local canMove = true
local stop = false

stopBindable.Event:Connect(function()
stop = true
end)

for i = 1, 10 do -- exaample loop
local event
event = Hum.MoveToFinished:Connect(function() -- since this won't yield
event:Disconnect()
canMove = true
end)

repeat wait() until stop or canMove do end -- this was my way but it was still jittering

end

Unfortunately it was glitchy when moving to points

I put my MoveTo in a repeat (since it stops after 8 secs) and had it repeat until the NPC position was within “X” studs of goal position. If you play the distance value a bit you can get it to follow a path without glitch hopping.

I’m not sure how you did that could you show some examples? It sounds you you didn’t use pathfinding if u repeated until an NPC position was X studs of aa goal position.

I used the built in pathfinding service only to generate waypoints. After than I use a custom function to apply the MoveTo.

something like this:

repeat
    wait()
    NPC.Humanoid:MoveTo(myPos)
until (NPC.HumanoidRootPart.Position - myPos).Magnitude <= 5

To be honest I find that fairly inefficient (as it can mess up the path if your humanoid agent sizing differs which mine does) and the method is fairly similar to what I’ve done so I doubt that will remove it. Thanks for trying though.

Np, I will say though that it works quite well for me. My NPCs can go anywhere and they do it smoothly. I also adjust the distance based on what speed they are traveling. I’m sure you could do the same for size.

I’ll give your idea a try tomorrow. Again, thanks for the idea as it does help to get as much feedback as possible.

The way you showed you were doing this still relied on the moveToFinished and a bindableEvent (i’m not sure when this event is fired) where as my version the moment you call MoveTo with a new position it continues without a stop, the humanoid simply changes direction and continues moving. I’m guessing the glitchy bits your experiencing are due to the stopping before switching to the next position. In any case, hope this helps in some way. Good luck with your project. :slightly_smiling_face:

Well, I changed it when @C_Sharper suggested repeat wait() post #3

After testing it, it wasn’t working well but today I woke up with an idea, my idea is that I will get the Humanoid to move towards where the mouse is by 0.1 or so because I believe that the issue is because of when the Event is received it moves the Humanoid back to it’s position (which the purpose is to intentionally stop the MoveToFinished yield)

If this method doesn’t work, I will probably add a BindableEvent which fires upon MoveToFInished and then when I need it to end immediately rather then using :MoveTo I would just fire the bindable.

These are my plans for today but I’m still open to any new suggestions.

EDIT: To all of those who’ve wandered upon this topic, my solution would be to make a table for each individual npc logging their way points and simpily updating their waypoints. For example, if a NPC is currently on waypoint 1 and you reupdate their way points, reset the waypoints values for 2+. This is probably the best way to have a smooth transition between each point without having the NPC to move to where it’s currently located at.