Asking for help about Target Tracking in Pathfinding

  1. What do you want to achieve?
    Like in most games in Roblox that involve NPCs as a threat, it requires good pathfinding. My goal is to create a function in my pathfinding system that allows for consistent and effective target tracking.

  2. What is the issue?
    In my current version of the script, the NPC follows a determined single path as it is instructed. However, when I want the NPC to follow a target that moves constantly; it gets confused and is unable to figure out where to go next while also trying to reach the target. View the recorded footage for clarification of the problem.

  3. What solutions have you tried so far?
    I tried coming up with revisions of the “pursuitTarget()” function. The following solutions are:

I. If the target is not moving, then it will create one singular path. Otherwise, constantly create paths that lead to the current position of the target.
Result: Only works well when the target is not moving, but breaks again when the target is motion.

II. If the target is no more than 4 studs away from the last waypoint, create one singular path. Otherwise, constantly create paths that lead to the current position of the target.
Result: Does not perform consistently well and eventually breaks.

Recording of the Problem (YouTube)

I would greatly appreciate any help!

Pathfinding = game:GetService("PathfindingService")
Parameters = {
	AgentRadius = 2,
	AgentHeight = 5,
	AgentCanJump = true,
	AgentCanClimb = true,
	WaypointSpacing = 4,
	Costs = {},
}

NPC = script.Parent
Control = NPC.Humanoid
Root = NPC.HumanoidRootPart

chaseRange = 60
captureRange = 2

local path local waypoints local nextwaypoint local blockedconnection local reachedconnection

function Cleanup () -- Prevent memory leaks.
	
	path = nil
	waypoints = nil
	nextwaypoint = 0
	
	if blockedconnection then
		blockedconnection:Disconnect()
		blockedconnection = nil
	end
	
	if reachedconnection then
		reachedconnection:Disconnect()
		reachedconnection = nil
	end
		
end

function newPath (Goal: Vector3) -- Path computation and creation.
	
	if path then Cleanup() end
	path = Pathfinding:CreatePath(Parameters)
	
	if path then
		local success, errorMessage = pcall(function() path:ComputeAsync(Root.Position, Goal) end)
		
		if success and path.Status == Enum.PathStatus.Success then
			print("Successfully computed path.") return path
		else warn("Unable to compute path: ", path.Status, errorMessage) end	
	end
	
end

function followPath (Goal: Vector3) -- Create path and follow.
	
	path = newPath(Goal)
	
	if path then	
		waypoints = path:GetWaypoints()
		nextwaypoint = 2
		
		reachedconnection = Control.MoveToFinished:Connect(function(reached)
			
			if reached and nextwaypoint < #waypoints then
				nextwaypoint += 1 print("Moving to: "..nextwaypoint)
				
				Control:MoveTo(waypoints[nextwaypoint].Position)
				if waypoints[nextwaypoint].Action == Enum.PathWaypointAction.Jump then
					task.wait(.15)
					Control.Jump = true 
				end
			else
				print("Path finished.")
				Cleanup()
			end
			
		end)
		
		blockedconnection = path.Blocked:Connect(function(blockedwaypoint)
			
			if blockedwaypoint >= nextwaypoint then
				print("Path blocked, retrying.") followPath(Goal)
			end
			
		end)

		Control:MoveTo(waypoints[nextwaypoint].Position)	
	end
	
end

function pursuitTarget (Target: Part) -- Follow a target constantly until captured or out of range.
	
	while
		(Target.Position-Root.Position).Magnitude < chaseRange
		and -- Check if the target is within the chase range and outside the capture range.
		(Target.Position-Root.Position).Magnitude > captureRange
	do
		task.wait()
		
		followPath(Target.Position)
		
	end	
	
end

task.wait(3)

--followPath(workspace:FindFirstChild("Goal",true).Position)
pursuitTarget(workspace.Winston_Adams.PrimaryPart)