solved old topic solved old topic solved old topic
I’ve been working with ControllerManager too, and I totally get your frustration — it doesn’t have a built-in .MoveToFinished event like Humanoid:MoveTo(), so detecting arrival isn’t as straightforward.
But don’t worry! Here are a few solid strategies that can help make this more reliable:
- Use a Region-Based Arrival Check (Better Than Magnitude)
Instead of checking raw .Magnitude every frame (which can be noisy due to slight model jitters), try defining a small radius or region and check if the NPC’s HumanoidRootPart is within that area.
Here’s a simple example:
local ARRIVAL_RADIUS = 2
function hasReachedPosition(npc, targetPosition)
local root = npc:FindFirstChild("HumanoidRootPart")
if root then
local horizontalDist = (Vector3.new(targetPosition.X, 0, targetPosition.Z) - Vector3.new(root.Position.X, 0, root.Position.Z)).Magnitude
local verticalDist = math.abs(targetPosition.Y - root.Position.Y)
return horizontalDist <= ARRIVAL_RADIUS and verticalDist <= 3
end
return false
end
Call this check in a loop or use RunService.Heartbeat until it’s true.
- Use Waypoints from PathfindingService
If you’re using PathfindingService, it gives you waypoints. You can move the NPC toward each one, and after each movement, use the arrival check above.
for i, waypoint in ipairs(path:GetWaypoints()) do
controllerManager:MoveTo(waypoint.Position)
repeat
RunService.Heartbeat:Wait()
until hasReachedPosition(npc, waypoint.Position)
end
This mimics Humanoid:MoveTo() behavior pretty closely and works well with ControllerManager.
- ControllerManager Doesn’t Have Events — So You Need Polling
Unfortunately, as of now, ControllerManager doesn’t fire events like MoveToFinished. So yes — polling (looping + checking position) is currently the safest method unless Roblox adds more event-driven APIs in the future.
You can optimize your polling to avoid checking every frame — maybe check every 0.1 seconds using task.wait(0.1) instead of RunService.Heartbeat.
Bonus Tip: Add Debug Visuals!
When debugging NPC movement, it’s super helpful to visualize waypoints and destination zones using Part instances or drawing tools like DrawingService (via plugins).
Summary
• Use a radius-based position check (instead of raw magnitude every frame).
• For pathfinding, loop through waypoints and wait until each one is reached.
• Since ControllerManager lacks movement events, polling is necessary — but you can do it smartly.
Yes, I’ve tested this method (and several others) in real scenarios, and I can confirm that it’s quite reliable within the current limitations of ControllerManager. The region-based check (instead of relying solely on .Magnitude) has proven to be more stable and less prone to false positives caused by slight model jitters or physics updates.
That said, this is just a suggested approach — not the only way to handle arrival detection. The goal was to provide a solid and practical starting point that mimics Humanoid:MoveTo() behavior, especially since ControllerManager doesn’t fire movement-completion events.
There are definitely other valid methods depending on your needs (e.g., higher precision, performance optimization, custom pathing). The key is finding a solution that fits your project’s requirements.
Hope this gives you a useful base to work from.
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.