How to make a procedural pathfinding NPC

Hello,

I’m working on a Pathfinder script, but I’m encountering an issue where the NPCs are not navigating around objects. Instead, they collide with them. This becomes a problem when the player stands behind an object, as the NPC fails to recalculate a new path around the object.

This is the script:

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 waypoints
local nextWaypointIndex
local reachedConnection
local blockedConnection

local function findTarget()
	local maxDistance = 200  --The farest away distance that the "Zombie" starts to follow a player
	local nearestTarget

	for index, player in pairs(Players:GetPlayers()) do
		if player.Character then
			local target = player.Character
			local distance = (Character.HumanoidRootPart.Position - target.HumanoidRootPart.Position) .Magnitude

			if distance < maxDistance and target.Humanoid.Health > 0 then
				nearestTarget = target
				maxDistance = distance
			end

			if distance < 4 then
				nearestTarget.Humanoid:TakeDamage(3)
			end
		end
	end

	return nearestTarget
end

local function followPath(destination)

	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)

		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)
	else
--		warn("Path not computed!", errorMessage)
	end
end

while wait() do
	local target = findTarget()
	if target then
		print(target.Name)
		followPath(target.HumanoidRootPart.Position)
	end
end

local npcRootPart = script.Parent.HumanoidRootPart
npcRootPart:SetNetworkOwner(nil)