humanoid:MoveTo() stopping short of the position it is supposed to move to

the character in my tower defense game stops short of the waypoints that have been outlined and begins to the next one, making his walk diagonal. I want to make it so the character can only start moving to the next waypoint if he is in the middle of part


sorry for the short video

1 Like

Does that gray part have collisions on? Maybe he is stuck on the part

Is your code waiting for the HumanoidRootPart to touch the target waypoint part? Looks like the humanoid switches direction as soon as the root part touches it. The only other reasons are :MoveTo() timing out, or it just decides it has reached the goal already for some unknown reason.

In my experience, I’ve found :MoveTo() somewhat unreliable especially when detecting if it’s already at the target position, so I just use :Move(targetDirection) until the humanoid is close enough to move to the next waypoint.

the gray part has collisions enabled, yes

So you’re saying that he can’t move through the part?

here is the code, it doesn’t wait for the humanoid root part to touch. it waits for the humanoid to say it’s done

function move(mob, map)
	local humanoid = mob:WaitForChild("Humanoid")
	local waypoints = map.Waypoints

	for waypoint = 1, #waypoints:GetChildren() do
		local currentwaypoint = waypoints[waypoint]
		local waypointpos = currentwaypoint.Position
		
		humanoid:MoveTo(waypointpos, currentwaypoint)
		humanoid.MoveToFinished:Wait()
	end
	
	mob:Destroy()
end

i meant to say the collisions are off, mb

The Humanoid:MoveTo() function has a timeout of 8 seconds, so if it doesn’t reach the waypoint in 8 seconds it will think that it reached the waypoint

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(reached)
		end
	end)

	-- start walking
	humanoid:MoveTo(targetPoint)

	-- execute on a new thread so as to not yield function
	task.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)
			task.wait(6)
		end

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

Use this custom move to function to remove the timeout.

The code is included in the official docs

1 Like

Strange. How long does it take for the mob to reach the waypoint?

Also remove the task.spawn so it doesn’t run a on a new thread. So your original code can wait for the function to finish

can you be more specific? what do i replace it with?

Create the function that i sent in the start of the script and replace the original moveto function with the custom function. Pass in the humanoid and the target point

1 Like

what is the “and then” parameter used for?

It runs the andThen function when the moving is finished, in your case you don’t need and andThen function so you can leave it empty. But don’t forget to remove the task.spawn function to let your script wait until the movement is done

so remove the entire function?

No, only remove the line that says task.spawn().

so like this?

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(reached)
		end
	end)

	-- start walking
	humanoid:MoveTo(targetPoint)

	-- execute on a new thread so as to not yield 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)
		task.wait(6)
	end

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

Yes, did you replace your original :MoveTo with this function?

yes, but how do i tell when the humanoid has stopped moving

This function already yields until the moving is done since you removed the spawn function