Pathfinding NPC becoming laggy with time

robloxapp-20250111-1532110.wmv (6.3 MB)

I’m new to code so i used ChatGPT to make my code less laggy, and it didn’t helped, you can see results on video.

Here is the code:

local Pathfinding = game:GetService("PathfindingService")
local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

local path = Pathfinding:CreatePath({
	AgentHeight = 6;
	AgentRadius = 3;
	AgentCanJump = false;
	Costs = {
		Water = 100;
		DangerZone = math.huge
	}
})

local Character = script.Parent
local humanoid = Character:WaitForChild("Humanoid")
local isChasing = Character:FindFirstChild("IsChasing") 

local waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection
local currentTarget  


local function updateChasingValue(target, value)
	if typeof(target) == "Instance" then
		if target:IsA("Player") then
			local chasingValue = target:FindFirstChild("Chasing")
			if chasingValue and chasingValue:IsA("BoolValue") then
				chasingValue.Value = value
			end
		elseif target:IsA("Model") and target:FindFirstChild("Humanoid") then
			local player = Players:GetPlayerFromCharacter(target)
			if player then
				updateChasingValue(player, value) 
			end
		end
	end
end


local function findTarget()
	local maxDistance = 50
	local nearestTarget

	for _, player in pairs(Players:GetPlayers()) do
		if player.Character and player.Character:FindFirstChild("Humanoid") and player:FindFirstChild("Safe") and player:FindFirstChild("Hidden") then
			local target = player.Character
			local targetHumanoid = target.Humanoid
			local targetPosition = target.HumanoidRootPart.Position
			local distance = (Character.HumanoidRootPart.Position - targetPosition).Magnitude

		
			if targetHumanoid.Health > 0 and not player.Safe.Value and not player.Hidden.Value then
			
				if currentTarget == player then
					if distance > maxDistance then
					
						updateChasingValue(player, false)
						currentTarget = nil
					else
						return target 
					end
				else
					local raycastParams = RaycastParams.new()
					raycastParams.FilterDescendantsInstances = {Character, target}
					raycastParams.FilterType = Enum.RaycastFilterType.Exclude

					local origin = Character.HumanoidRootPart.Position
					local direction = (targetPosition - origin).Unit * maxDistance
					local raycastResult = workspace:Raycast(origin, direction, raycastParams)

					if not raycastResult or raycastResult.Instance:IsDescendantOf(target) or not raycastResult.Instance.CanCollide then
						if distance < maxDistance then
							nearestTarget = target
							maxDistance = distance
						end
					end
				end
			end
		end
	end

	return nearestTarget
end

local function followPath(destination)
	if blockedConnection then
		blockedConnection:Disconnect()
		blockedConnection = nil
	end

	if reachedConnection then
		reachedConnection:Disconnect()
		reachedConnection = nil
	end

	local success, errorMessage = pcall(function()
		path:ComputeAsync(Character.PrimaryPart.Position, destination)
	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(destination)
			end
		end)

		reachedConnection = humanoid.MoveToFinished:Connect(function(reached)
			if reached and nextWaypointIndex < #waypoints then
				nextWaypointIndex += 1
				humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
			else
				reachedConnection:Disconnect()
				reachedConnection = nil
				blockedConnection:Disconnect()
				blockedConnection = nil

				if currentTarget then
					updateChasingValue(currentTarget, false)
					currentTarget = nil
					if isChasing then
						isChasing.Value = false
					end
				end
			end
		end)

		nextWaypointIndex = 2
		humanoid:MoveTo(waypoints[nextWaypointIndex].Position)
	end
end

Players.PlayerRemoving:Connect(function(player)
	if currentTarget == player then
		updateChasingValue(player, false)
		currentTarget = nil
		if isChasing then
			isChasing.Value = false
		end
	end
end)

while wait() do
	local target = findTarget()

	if target then
		if isChasing and not isChasing.Value then
			isChasing.Value = true
		end

		local player = Players:GetPlayerFromCharacter(target)
		if player then
			if currentTarget ~= player then
				if currentTarget then
					updateChasingValue(currentTarget, false)
				end
				updateChasingValue(player, true)
				currentTarget = player
			end
		end

		if target:FindFirstChild("HumanoidRootPart") then
			followPath(target.HumanoidRootPart.Position)
		end
	else
		if isChasing and isChasing.Value then
			isChasing.Value = false
		end

		if currentTarget then
			updateChasingValue(currentTarget, false)
			currentTarget = nil
		end
	end
end