Constantly Updating Pathfinding Path

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.

2 Likes

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.

3 Likes

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.

1 Like

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
2 Likes

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
17 Likes