Zombie AI Stutters While Following Player, How to Fix?

I’m working on zombie AI for my Roblox game and running into a problem with choppy movement. The zombies are able to follow the player using PathfindingService, but the movement looks stuttery and unnatural like they move to each waypoint, stop, then move again.

local PathFindingService = game:GetService("PathfindingService")

local ZombieBase = {}
ZombieBase.__index = ZombieBase

function ZombieBase.new(zombieModel)
	local self = setmetatable({}, ZombieBase)
	self.Model = zombieModel
	self.Humanoid = zombieModel:FindFirstChild("Humanoid")
	self.Hrp = zombieModel:FindFirstChild("HumanoidRootPart")
	self.TargetPlayer = nil
	return self
end

function ZombieBase:StartAI()
	task.spawn(function()
		while self.Model and self.Model.Parent do
			self:UpdateTargetPlayer()

			if self.TargetPlayer ~= nil then
				local path = PathFindingService:CreatePath()
				path:ComputeAsync(self.Hrp.Position, self.TargetPlayer.Character.HumanoidRootPart.Position)

				if path.Status == Enum.PathStatus.Success then
					for _, waypoint in pairs(path:GetWaypoints()) do
						if self.Model and self.Model.Parent then
							self.Humanoid:MoveTo(waypoint.Position)
							self.Humanoid.MoveToFinished:Wait()
						end
					end
				end
			end

			task.wait(0.5)
		end
	end)
end

function ZombieBase:UpdateTargetPlayer()
	local players = game.Players:GetPlayers()
	local closestPlayer = nil
	local shortestDistance = math.huge

	for _, player in ipairs(players) do
		local character = player.Character
		if character and character:FindFirstChild("HumanoidRootPart") then
			local dist = (character.HumanoidRootPart.Position - self.Hrp.Position).Magnitude
			if dist < shortestDistance then
				shortestDistance = dist
				closestPlayer = player
			end
		end
	end

	self.TargetPlayer = closestPlayer
end

return ZombieBase

What I Want:

  • Smooth continuous movement as the zombie follows the player (like basic chasing enemies in most games).

I was dealing with this issue before, my solution was to update the Network Owner to nil (the server) pretty often, as the jittery-ness was caused by the network owner changing to the closest player.

You should only need to set the network owner once, as once it’s set, it won’t change again automatically.