Zombie pathfinding npc is a jerk and crashes into the walls

hi, recently been coding a script about a zombie chasing the player with pathfinding
for a I think fps game

but I have only two problems…

Crash into the walls and isnt very good

Gonna throw my Pc
throw-out-rage

Well let’s get to the point, here is the script:

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

-- Basic configuration
local ZOMBIE_SPEED = 16  -- Speed at which the zombie moves
local UPDATE_INTERVAL = 0.1  -- Time interval for updating the zombie's path
local ATTACK_RANGE = 4  -- Distance at which the zombie can attack

local zombie = script.Parent  -- Reference to the zombie character
local humanoid = zombie:WaitForChild("Humanoid")  -- Reference to the humanoid component of the zombie
local rootPart = zombie:WaitForChild("HumanoidRootPart")  -- Reference to the root part of the zombie

-- Configure the pathfinding settings
local path = PathfindingService:CreatePath({
	AgentRadius = 2,  -- Radius of the pathfinding agent (zombie)
	AgentHeight = 5,  -- Height of the pathfinding agent
	AgentCanJump = true,  -- Allows the pathfinding agent to jump
	WaypointSpacing = 4  -- Spacing between waypoints
})

-- Find the nearest player
local function findNearestPlayer()
	local nearestDistance = math.huge  -- Initialize with a large number
	local nearest = nil  -- Initialize with no player

	for _, player in ipairs(Players:GetPlayers()) do  -- Iterate through all players
		local character = player.Character  -- Reference to the player's character
		if character and character:FindFirstChild("HumanoidRootPart") then  -- Check if the character has a root part
			local playerRoot = character.HumanoidRootPart  -- Reference to the player's root part
			local distance = (playerRoot.Position - rootPart.Position).Magnitude  -- Calculate distance to the zombie
			if distance < nearestDistance then  -- Check if this is the closest player
				nearestDistance = distance  -- Update nearest distance
				nearest = player  -- Update nearest player
			end
		end
	end

	return nearest  -- Return the nearest player
end

-- Follow the path to the target
local function followPath(waypoints)
	for i, waypoint in ipairs(waypoints) do  -- Iterate through the waypoints
		if waypoint.Action == Enum.PathWaypointAction.Jump then  -- Check if the waypoint requires jumping
			humanoid.Jump = true  -- Make the zombie jump
		end
		humanoid:MoveTo(waypoint.Position)  -- Move the zombie to the waypoint
		if (rootPart.Position - waypoint.Position).Magnitude < 4 then  -- Check if the zombie is close to the waypoint
			continue  -- Skip to the next waypoint
		end
		task.wait(0.1)  -- Wait before moving to the next waypoint
	end
end

-- Main loop
while task.wait(UPDATE_INTERVAL) do  -- Repeat every UPDATE_INTERVAL seconds
	local target = findNearestPlayer()  -- Find the nearest player
	if target and target.Character then  -- Check if a target is found
		local targetRoot = target.Character:FindFirstChild("HumanoidRootPart")  -- Reference to the target's root part
		if targetRoot then
			local success, errorMessage = pcall(function()  -- Try to compute the path
				path:ComputeAsync(rootPart.Position, targetRoot.Position)  -- Compute path to the target
			end)

			if success and path.Status == Enum.PathStatus.Success then  -- Check if the path is valid
				followPath(path:GetWaypoints())  -- Follow the computed path
			else
				humanoid:MoveTo(targetRoot.Position)  -- Move directly to the target if path computation fails
			end
		end
	end
end

so uhhh I think I should put videos on the problem:


and also this happens:

The problem appears to be your MoveTo and waiting for the NPC to complete the move:

		humanoid:MoveTo(waypoint.Position)  -- Move the zombie to the waypoint
		if (rootPart.Position - waypoint.Position).Magnitude < 4 then  -- Check if the zombie is close to the waypoint
			continue  -- Skip to the next waypoint
		end
		task.wait(0.1)  -- Wait before moving to the next waypoint

The if portion of the above will only be validated once. Change the if statement to a while and it should fix the problem.

Alternatively, get rid of the if statement and use ```MoveToFinished:Wait(), so you definitely know the NPC has reached it’s goal before navigating to the next waypoint.