Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

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

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

✓ Accepted answer

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

This discussion is preserved as it was. New answers, comments, and votes are closed.