I am making a K9 unit, I want the K9 to be constantly following me unless attacking a person but when I use the pathfinding service it will only create the path once and won’t update the path. I am looking for a code sample with a solution please as I’m not fully familiar with the service.
You can update the path by calling :ComputeAsync() again and updating your waypoints with the same path instance (similar to the initial path creation). How often and what triggers that recompilation is totally up to your optimization design. It could be every second or it could be after the humanoid hits two waypoints.
But a path script is a bit involved. So I refer you to this article which u may have already read. It has code for designing a path script, and it does have an implementation for updating the path when the path becomes blocked. So try and understand that code, and use it to update the path on a more constant interval.
But be optimal when updating the path; using a while wait() loop to update it is going to be heavy on computation cost.
Does the ComputeAsync function update the waypoints?
Yeah, it updates the waypoints. But it stores the updated waypoints in a new table at a different memory address.
So you’ll just have to call path:GetWaypoints() after updates to get the new set.
Hello, I’ve tried doing what you said but it doesn’t work
My NPC does walk, but it’s like the path doesn’t update, it still goes through the same path and doesn’t go towards the player.
Here is my script :
local PathfindingService = game:GetService("PathfindingService")
local NPC = script.Parent
local Humanoid = NPC.Humanoid
local Destination = game.Players:WaitForChild("banopitu").CharacterAdded:Wait()
local Path = PathfindingService:CreatePath()
Path:ComputeAsync(NPC.PrimaryPart.Position, Destination.PrimaryPart.Position)
local Waypoints = Path:GetWaypoints()
for _, waypoint in pairs(Waypoints) do
Humanoid:MoveTo(waypoint.Position)
Humanoid.MoveToFinished:Wait()
Path:ComputeAsync(NPC.PrimaryPart.Position, Destination.PrimaryPart.Position)
local NewWaypoints = Path:GetWaypoints()
end
Right, so several things are kind of happening here.
You do successfully recompute the path in your loop, but you actually never do anything with the new points ( local NewWaypoints = Path:GetWaypoints()
). All that is ever happening is iterating over the waypoints returned from the first time you called :GetWaypoints()
.
A for loop is actually not the best structure to use (alone), because you want to iterate over points that are constantly changing in a non-linear order. Every time the path recomputes, you should then follow the 1st waypoint. But computing paths take time, so you don’t want it to be happening in between movement logic. So you’ll want those happening synchronously with coroutines or something.
Here’s one approach, the results should get you what you want.
local PathfindingService = game:GetService("PathfindingService")
local RunService = game:GetService('RunService')
local NPC = script.Parent
local Humanoid = NPC.Humanoid
local Destination = game.Players:WaitForChild("banopitu").CharacterAdded:Wait()
local Path = PathfindingService:CreatePath()
Path:ComputeAsync(NPC.PrimaryPart.Position, Destination.PrimaryPart.Position)
local activeCoroutine = nil
local follow=true
-- Loop update
coroutine.wrap(function()
while (follow) do
wait(1/3)
update()
end
end)()
function update()
Path:ComputeAsync(NPC.PrimaryPart.Position, Destination.PrimaryPart.Position)
local Waypoints = Path:GetWaypoints()
table.remove(Waypoints, 1) -- First waypoint seems to always be origin
coroutine.wrap(followPath)(Waypoints) -- Follow new path
end
function followPath(waypoints)
activeCoroutine = coroutine.running()
for _, point in ipairs(waypoints) do
if activeCoroutine~=coroutine.running() then
return end -- No longer active path
Humanoid:MoveTo(point.Position)
Humanoid.MoveToFinished:Wait()
if point.Action==Enum.PathWaypointAction.Jump then
Humanoid.Jump = true end
end
end
local NPC = script.Parent
local NPCPart = NPC.HumanoidRootPart
local NPCHuman = NPC.Humanoid
local Pathfind = game:GetService("PathfindingService")
local Path = Pathfind:CreatePath()
local function FindTarget()
local Range = 50
local Target
for _, v in pairs(workspace:GetChildren()) do
local Humanoid = v:FindFirstChild("Humanoid")
local Torso = v:FindFirstChild("HumanoidRootPart")
if Humanoid and Torso and v ~= NPC then
if (NPCPart.Position - Torso.Position).Magnitude <= Range then
Target = Torso
end
end
end
return Target
end
while task.wait() do
if FindTarget() then
local PathCompute = Path:ComputeAsync(NPCPart.Position, FindTarget().Position)
for i, v in pairs(Path:GetWaypoints()) do
NPCHuman:MoveTo(v.Position)
task.wait(0.01)
if i >= 2 then
print("ay")
break
end
end
else
for i, v in pairs(workspace.Waypoints:GetChildren()) do
Path:ComputeAsync(NPCPart.Position, v.Position)
for i2, v2 in pairs(Path:GetWaypoints()) do
NPCHuman:MoveTo(v2.Position)
local finished = NPCHuman.MoveToFinished:Wait()
if FindTarget() then
break
end
end
end
end
end
if anyone has problems, this script works fine to me. It may be not the best, but it works with a waypoint folder
I got an issue. The animation that plays when the npc walks jitters due to the fact it’s starting and stopping moving every few milliseconds, how would I fix this?