Humanoid:MoveTo is unreliable?

I am making a NPC system that follows the player as they move using Pathfinding. The Pathfinding code is modified from the wiki, as the wiki uses Humanoid.MoveToFinished being used to move the character through the waypoints.

It works decently well, but it’s not perfect. Often times, the NPC runs in place as a result of the running animation being played but the NPC not moving. Here is my output for debugging:

image

As you can guess, the numbers refer to a waypoint index. In the lines with "MoveTo Finished: ", the first number is the waypoint that the NPC was trying to reach, and the 2nd number is the total number of waypoints. The third bool value is whether the NPC reached it or not.

Everytime :MoveTo is called, “Moving To: waypointNum” is printed, so this means that :MoveTo is being called for waypoint 11, but for some reason, it’s not being completed. I’ve verified that there’s no obstacles in the way of the NPC, as it’s just flat land.

Maybe MoveTo is weird? I would post code but it’s decently long, and I want you to trust my printing skills…

Things I’ve Tried:
-Shorter timeout function that recalls MoveTo as given by the MoveTo documentation on wiki
-Having an even shorter timeout (.1 seconds) instead of the given one above in the wiki
-Trying it on a real server rather than in studio to see if it makes a difference

2 Likes

The :MoveTo() event times out after 8 seconds. This wiki explains why and gives code on how to fix it.

1 Like

You should uses Humanoid.MoveDirection.Magnitude to detect if the NPC is moving and so when to play animation.

1 Like

But why doesn’t the NPC complete it’s goal? Is there no rhyme or reason? It seems kind of random to stop at 11…

1 Like

Also the code that’s used to fix it also doesn’t work. The code basically sets a shorter timeout and then recalls the :MoveTo(), but even that doesn’t work:
N.B. I start at waypoint 2 instead of 1
image

Here is my implementation, where the only print statements occur:

MoveTo = function(humanoid, targetPoint)
	local targetReached = false
	local connection
	connection = humanoid.MoveToFinished:Connect(function(reached)
		print('MoveTo Finished: ', WaypointIndex, #WaypointArray, true)
		targetReached = true
		connection:Disconnect()
		connection = nil
	end)

	print('Moving To: ', WaypointIndex)
	humanoid:MoveTo(targetPoint)

	coroutine.wrap(function()
		while not targetReached do
			if not (humanoid and humanoid.Parent) then
				break
			end
			if humanoid.WalkToPoint ~= targetPoint then
				break
			end
			humanoid:MoveTo(targetPoint)
			wait(1)
			print('MoveTo Finished: ', WaypointIndex, #WaypointArray, false)
		end

		if connection then
			connection:Disconnect()
			connection = nil
		end
	end)()
end

Nevermind, I tested the :MoveTo() function on a baseplate with the NPC with a simple while loop implementation. Overcalling MoveTo doesn’t break it nor does it break randomly within a time period… so the conclusion is that MoveTo is reliable.

I will investigate this issue further and come up with the real cause. My next guess is that it may be my positioning or the MoveToFinished event, but I’ll figure it out since I’m not sure.

I apologize for wasting anyone’s time.

I’ve fixed the issue by implementing a loop that uses magnitude-based checking, which was much more reliable than the Humanoid.MoveToFinished.

I don’t know if this means that MoveToFinished is unreliable, but it definitely points to something. I was able to polish my pathfinding pretty well with my own optimizations.