I have made a Zombie Artificial Intelligence script that chases the nearest player to the zombie using a mixture of pathfinding, raycasting and the MoveTo() function. The overall gist of the code works, however the zombie keeps pausing after each waypoint and this is just not practical.

Heres the code I wrote:

local pathfindingservice = game:GetService("PathfindingService")

local db = false

local torso = nil
local torsochar = nil

local zombie = script.Parent:WaitForChild("Zombie")
local me = script.Parent:WaitForChild("Head")
script.Parent.PrimaryPart:SetNetworkOwner(nil)
local target = nil
local aim
local path
local a = 1
local movetotimeout = 0
local movementdone = false

local chooserdb = false



function FindNearest(position)
	local lowest = math.huge -- infinity
	local NearestPlayer = nil
	for i,v in pairs(game.Players:GetPlayers())do
		if v and v.Character then
			local distance = v:DistanceFromCharacter(position)
			if distance < lowest then
				lowest = distance
				NearestPlayer = v
			end
		end
	end
	return NearestPlayer
end

function targetposition()
	torso = FindNearest(me.Position) 
	if torso ~= nil then
		torsochar = game.Workspace:FindFirstChild(torso.Name)
--		print("torsochar"..tostring(torsochar.HumanoidRootPart.Position))
		target = torsochar.HumanoidRootPart.Position
	end
	return target
end

-- if target is within a radius and raycasting shows that there is nothing in the way, 
-- use MoveTo (on loop) but if ray casting shows something in the way then use pathfinder.


function movementchooser()
	if chooserdb == false then
		chooserdb = true
		local barrierfinder = Ray.new(me.Position, (targetposition() - me.Position).Unit * 500)
		local hit, position = game.Workspace:FindPartOnRayWithIgnoreList(barrierfinder, script.Parent:GetChildren())
		if hit == torsochar:WaitForChild("RayHitbox") then
			print("MoveTo selected")
				chooserdb = false
			return "MoveTo"
		else
			print("PathFind Selected")
				chooserdb = false
			return "Pathfind"
		end
	end
end


function Pathfinding()
	aim = targetposition()
	path = pathfindingservice:CreatePath()
	path:ComputeAsync(me.Position, aim)
	local waypoints = path:GetWaypoints()
	for i, waypoint in pairs(waypoints)do
		if waypoint.Action == Enum.PathWaypointAction.Jump then
			zombie:ChangeState(Enum.HumanoidStateType.Jumping)
		end
		zombie:MoveTo(waypoint.Position)
		zombie.MoveToFinished:Wait()
	end
	return "done"	
end


function MoveTo()
	print("MoveTo Activated")
	movementdone = false
	movetotimeout = 0
	zombie:MoveTo(targetposition())
	while movetotimeout < 1 do
		wait(0.1)
		movetotimeout = movetotimeout + 0.1
		print("MoveTo Check", movetotimeout)
	end
	if movetotimeout >= 1 then
		print("timed out")
		movementchooser()
		if movementchooser() == "Pathfind" then
			Pathfinding()
			repeat
				wait()
			until Pathfinding() == "done"
		end
	else
		if zombie.MoveToFinished == true then
			print("MoveTo Finished")
			movementdone = true
			return "Done"
		end		
	end
		movementdone = true
		return "Done"
end



wait(15)
while true do
	MoveTo()
	repeat
		wait()
	until movementdone == true
	wait()
end

I would prefer to only use pathfinding service however I have found that it won't change target position when the nearest player moves.

Any suggestions will be very much appreciated, Thanks.