Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Humanoid:MoveTo seems to not work with slow speed NPCs?

Asked by 2 years ago
Edited 2 years ago

So i have a script that makes an NPC walk to certain waypoints then destroy itself, here's the script:

-- Waypoint Folder and Parts
local Waypoints = game.Workspace.Map.Waypoints
local Way1 = Waypoints:WaitForChild('Waypoint1')
local Way2 = Waypoints:WaitForChild('Waypoint2')
local Way3 = Waypoints:WaitForChild('Waypoint3')
local Way4 = Waypoints:WaitForChild('Waypoint4')
local Way5 = Waypoints:WaitForChild('Waypoint5')
local Way6 = Waypoints:WaitForChild('Waypoint6')

-- Self
local Self = script.Parent.Parent
local hum = Self:WaitForChild('Humanoid')
local Walk = hum:LoadAnimation(Self:WaitForChild('Walk'))

-- Move the Humanoid; Args > HumanoidRootPart + Waypoint Part
local function MoveHumanoid(humanoid, waypoint)
    humanoid:MoveTo(waypoint.Position)
    humanoid.MoveToFinished:Wait()
end

-- Repeat Function For All Waypoints
Walk:Play()
MoveHumanoid(hum, Way1)
MoveHumanoid(hum, Way2)
MoveHumanoid(hum, Way3)
MoveHumanoid(hum, Way4)
MoveHumanoid(hum, Way5)
MoveHumanoid(hum, Way6)

-- Delete the Enemy
Self:Destroy()

I use this script in many different NPCs (a fast walking one and a normal speed one) and it works fine until I put this script in a slow walk speed NPC. It moves to the first couple waypoints semi-fine but when it reaches the 3rd waypoint it goes half way and skips straight to the 5th. Any help is appreciated thanks!

1 answer

Log in to vote
1
Answered by 2 years ago

The reach goal state of a humanoid will timeout after 8 seconds if it doesn’t reach its goal. This is done so that NPCs won’t get stuck waiting for Humanoid.MoveToFinished to fire. If you don’t want this to happen, you should repeatedly call MoveTo so that the timeout will keep resetting.

The same link also has the code you'd require. Check the link if you need more context.

    local function moveTo(humanoid, targetPoint, andThen)
        local targetReached = false

        -- listen for the humanoid reaching its target
        local connection
        connection = humanoid.MoveToFinished:Connect(function(reached)
            targetReached = true
            connection:Disconnect()
            connection = nil
            if andThen then
                andThen()
            end
        end)

        -- start walking
        humanoid:MoveTo(targetPoint)

        -- execute on a new thread so as to not yield function
        spawn(function()
            while not targetReached do
                -- does the humanoid still exist?
                if not (humanoid and humanoid.Parent) then
                    break
                end
                -- has the target changed?
                if humanoid.WalkToPoint ~= targetPoint then
                    break
                end
                -- refresh the timeout
                humanoid:MoveTo(targetPoint)
                wait(6)
            end

            -- disconnect the connection if it is still connected
            if connection then
                connection:Disconnect()
                connection = nil
            end
        end)
    end
Ad

Answer this question