Agent "Stuttering" While Pathfinding

I keep running into this issue where my pathfinding agent just
“Stutters.”

Ive looked on the Hub, but cant find anything that fixes this stuttering problem. I tried one solution that would see how close the agent is to the waypoint, but no luck.

This is my code:

local PFS = game:GetService("PathfindingService")

local Params = {
	AgentRadius = 2,
	AgentHeight	= 5,
	AgentCanJump = true,
}

function GetNextWaypoint()
	
	local Path = PFS:CreatePath(Params)
	
	Path:ComputeAsync(script.Parent.HumanoidRootPart.Position,script.TargetPart.Value.Position)
	
	return Path:GetWaypoints()
	
end

while true do
	if script.TargetPart.Value ~= nil then
		
		local NextWaypoint = GetNextWaypoint()[2]
		local JumpWaypoint = GetNextWaypoint()[3]
		
		if NextWaypoint ~= nil and JumpWaypoint ~= nil then
			
			if JumpWaypoint.Action == Enum.PathWaypointAction.Jump then
				script.Parent.Humanoid.Jump = true
			end
		
			script.Parent.Humanoid:MoveTo(NextWaypoint.Position)
	
			repeat
				game["Run Service"].Heartbeat:Wait()
				--print((NextWaypoint.Position - script.Parent.HumanoidRootPart.Position).Magnitude)
			until (NextWaypoint.Position - script.Parent.HumanoidRootPart.Position).Magnitude <= Params.AgentHeight
			
		end
	end
end
1 Like

My best bet is that pathfinding might take a bit to calculate the next point, causing the stutter. After you start moving to the next waypoint, load the next path before you reach it. That way, you will only have delay at the beginning, which will be much more minimal then at each of the waypoints.

Short version: Have the next path loaded before the character reaches it

If you have any questions about anything, feel free to ask.

Your code seems to have a few excessive calls, that could be one reason for what you observe as problems.

1.
The first problem I see, is that you call GetNextWaypoint() twice, just to extract two different elements out of the (same) array the function returns. - So basically you call the (expensive) path-finding algorithm twice.

You should change that to just:

local AllWaypoints = GetNextWaypoint()  -- Only call once, and then store the result locally
local NextWaypoint = AllWaypoints[2]
local JumpWaypoint = AllWaypoints[3]

Note: There may also be problems with assuming that there always be 3 (or more) waypoints, as according to API docs for GetWaypoints, it could even return an empty array.

2.
Second issue I see, is that your function GetNextWaypoint(), creates a new Path object every time. That too may cause unneeded objects in memory.

According to the code samples I see on the Pathfinding tutorial page, there would only be a need to call PFS:CreatePath(...) one time, and then (re)use its result when needed.

So perhaps change your code, so you move the following statement outside the scope of the function GetNextWaypoint():

local Path = PFS:CreatePath(Params)

function ...

3.
A third issue is an anti-pattern I spot, with the repeated busy/wait loop for assuming the Humanoid’s position gets within distance of the wanted NextWaypoint.

In case the Humanoid is blocked from reaching that waypoint, you essentially have an infinite loop, because it will never reach the waypoint.

Instead of using a “wait loop”, I suggest you study the Handling Blocked Paths chapter, in particular the code and how it uses events Blocked and MoveToFinished for determining if/when the Humanoid reaches the intended waypoint.

4.
Lastly I also think, which may be the actual reason for the ‘stuttering’, is that you call Path:ComputeAsync for each-and-every completed movement to waypoint. It is an expensive operation to calculate a route from one position, through an unknown area, to a target position. So by continuously doing it each-and-every-single-step will absolutely cause slowdowns, or ‘stuttering’.

It will be much better, to only compute the waypoints once, and then iterate one-by-one through the array of waypoints, until either the Humanoid becomes blocked or has reached the last waypoint in the array.

The ‘Handling Blocked Paths’ chapter’s sample code in the Pathfinding tutorial shows how it could be done.

2 Likes