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:
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
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
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’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.