Pathfinding "lags" after it reached its destination for the first time

I’m trying to learn pathfinding with NPCs. My ideal goal will be to make my zombies follow the nearest player, so the destination location will change. I came across a problem where changing my example destination point makes my NPC lag for no reason after it reached there for the first time. It’s probably caused by my while loop down below. Does this mean I might be indexing my waypoints wrong?

Here is the script im using:

local ReplicatedFirst = game:GetService('ReplicatedFirst')
local PathfindingService = game:GetService('PathfindingService')

local Zombie = game.Workspace.Walker
local Spawnpoint = game.Workspace.SpawnLocation

local path = PathfindingService:CreatePath()

local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection

local function followPath()
	local humanoid = Zombie.Humanoid
	local humanoidRootPart = Zombie.HumanoidRootPart
	
	local success, errorMessage = pcall(function()
		humanoidRootPart:SetNetworkOwner(nil)
		path:ComputeAsync(humanoidRootPart.Position, Spawnpoint.Position)
	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()
			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()
				end
			end)
		end
		
		nextWaypointIndex = 2
		humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
	end
end

while task.wait(.2) do
	followPath()
end

You are calling “followPath” every 200ms (i.e. 5 times a second). Is this really necessary? It would be prudent to call this function using the wealth of checks within the function body that would tell the code when to attempt running the function again.

1 Like

I tried using while loop just to see if it actually works. Will for sure change it later when I add nearest player targeting.

You also call “followPath” from within the function itself. How can you be sure what sequence of events is occurring when the function is called externally and continuously, and possibly fired from within under the same conditional checks. Imagine how many versions of this function are executing concurrently on the same logic stream, changing/checking the same set of variables.

It only calls followPath() when the path.Blocked event fires, so I’m sure its occuring ONLY when path is not successful. I might not understand something about what you’re trying to tell me, as I said, I’m just learning this.

Also, why would it execute this function so many times if path.Blocked event occurs only once per computing?

On first entry to this function the path is calculated and success is checked here:

Now you set up the Blocked connection because the path is valid and never check beforehand if the blocked connection exists, i.e. the next call (200ms later) will get the same path and if successful it will connect Blocked once more.

Every time “followPath” is called you use the same position to calculate the path (i.e. Spawnpoint.Position) regardless of where the new path now starts because the path following object may have moved several waypoints from the initial spawn-point.