Hello everyone!
I’ve been trying to move “NPCs” around the map using the Pathfinding service, but ran into an issue while trying to send the NPC to another destination right after the move function was over.
It starts moving towards the destination but stops a little later as shown in this clip https://gyazo.com/0e33b00c4815d3d110cc4088d254fb6d
As i just started experimenting with the service, i used the code Here
I just slightly edited the code, adding a second destination, and a “function” that’s triggered when the destination was reached (line 37)
local PathfindingService = game:GetService("PathfindingService")
local hrp = script.Parent.HumanoidRootPart
local humanoid = script.Parent.Humanoid
local path = PathfindingService:CreatePath()
local TEST_DESTINATION = game.Workspace.Part1.Position
local TEST_DESTINATION2 = game.Workspace.Part2.Position
local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local function followPath(destination)
local success, errorMessage = pcall(function()
path:ComputeAsync(hrp.Position, destination)
end)
if success and path.Status == Enum.PathStatus.Success then
waypoints = path:GetWaypoints()
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
if blockedWaypointIndex >= nextWaypointIndex then
blockedConnection:Disconnect()
followPath(destination)
end
end)
if not reachedConnection then
reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
nextWaypointIndex += 1
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
followPath(TEST_DESTINATION2)
end
end)
end
nextWaypointIndex = 2
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn("Path not computed!", errorMessage)
end
end
followPath(TEST_DESTINATION)
Thank you in advance!
Just for organization purposes it’d be easier to have the followPath
function call on line 37 to be called outside the function and instead just disconnect everything if the move times out or is finished. I’ve really only messed around with PathfindingService | Roblox Creator Documentation a little bit and haven’t explored the new stuff they added to it yet.
I believe the problem may be that the reached connection variable is outside the function’s scope. This will cause
to only work once. Even though you disconnected it, it’s still an object that exist. Also, I don’t believe wrapping ComputeAsync
in a pcall
will work. If it fails it will instead just affect the Path | Roblox Creator Documentation. However, you can use the details of the different PathStatus | Roblox Creator Documentation enums to create an error code.
You can try this instead:
local PathfindingService = game:GetService("PathfindingService")
local hrp = script.Parent.HumanoidRootPart
local humanoid = script.Parent.Humanoid
local errors = {
[Enum.PathStatus.ClosestNoPath] = "Path doesn’t exist, returns path to closest point.",
[Enum.PathStatus.ClosestOutOfRange] = "Goal is out of MaxDistance range, returns path to closest point you can reach within MaxDistance.",
[Enum.PathStatus.FailStartNotEmpty] = "Failed to compute path; the starting point is not empty.",
[Enum.PathStatus.FailFinishNotEmpty] = "Failed to compute path; the finish point is not empty.",
[Enum.PathStatus.NoPath] = "Path doesn’t exist."
}
local path = PathfindingService:CreatePath()
local TEST_DESTINATION = game.Workspace.Part1.Position
local TEST_DESTINATION2 = game.Workspace.Part2.Position
local function followPath(destination)
path:ComputeAsync(hrp.Position, destination)
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
local nextWaypointIndex = 2
local blockedConnection
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
if blockedWaypointIndex >= nextWaypointIndex then
blockedConnection:Disconnect()
followPath(destination)
end
end)
local reachedConnection
reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
nextWaypointIndex += 1
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
end
end)
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn(errors[path.Status])
end
end
followPath(TEST_DESTINATION)
followPath(TEST_DESTINATION2)
I haven’t tried this yet, but i forgot to mention the output wasn’t printing any errors.
Instead, it’s not trying to move to the second destination now and nothing is printing in the output.
Try adding a print statement to see if it executes.
local function followPath(destination)
path:ComputeAsync(hrp.Position, destination)
if destination == TEST_DESTINATION then
print("Destination 1")
else
print("Destination 2")
end
-- other code in the function
yes they both execute, the npc first walks towards the first destination, then quickly switches to the second destination, then again to the first one and then it’s stuck there with no output errors
Alright so somehow the script decided to work after this, this is how it looks like.
local PathfindingService = game:GetService("PathfindingService")
local hrp = script.Parent.HumanoidRootPart
local humanoid = script.Parent.Humanoid
local errors = {
[Enum.PathStatus.ClosestNoPath] = "Path doesn’t exist, returns path to closest point.",
[Enum.PathStatus.ClosestOutOfRange] = "Goal is out of MaxDistance range, returns path to closest point you can reach within MaxDistance.",
[Enum.PathStatus.FailStartNotEmpty] = "Failed to compute path; the starting point is not empty.",
[Enum.PathStatus.FailFinishNotEmpty] = "Failed to compute path; the finish point is not empty.",
[Enum.PathStatus.NoPath] = "Path doesn’t exist."
}
local path = PathfindingService:CreatePath()
local TEST_DESTINATION = game.Workspace.Part1.Position
local TEST_DESTINATION2 = game.Workspace.Part1.Position
local function followPath(destination)
path:ComputeAsync(hrp.Position, destination)
if destination == TEST_DESTINATION then
print("Destination 1")
else
print("Destination 2")
end
if path.Status == Enum.PathStatus.Success then
local waypoints = path:GetWaypoints()
local nextWaypointIndex = 2
local blockedConnection
blockedConnection = path.Blocked:Connect(function(blockedWaypointIndex)
if blockedWaypointIndex >= nextWaypointIndex then
blockedConnection:Disconnect()
followPath(destination)
end
end)
local reachedConnection
reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
if reached and nextWaypointIndex < #waypoints then
nextWaypointIndex += 1
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
reachedConnection:Disconnect()
blockedConnection:Disconnect()
if destination == TEST_DESTINATION then
followPath(TEST_DESTINATION2)
else
followPath(TEST_DESTINATION)
end
end
end)
humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
else
warn(errors[path.Status])
end
end
followPath(TEST_DESTINATION)
i kept the
if destination == TEST_DESTINATION then
print("Destination 1")
else
print("Destination 2")
end
and in the function line 40, in the if statement line 45, i just sent the npc to the other location, which is what i’ve been doing since the start but didnt work
This might sound dumb, but somtimes printing something somewhere in the script fixed an issue, this happened to me before and the fix was just adding an empty print. probably just a delay issue.
ANYWAYS thank you so much for your help i really really appreciate it!