Why does my ai stutter to the side like this?

This is what it looks like, https://gyazo.com/2ab0115c18e7ae9cac296e8d3af50c21.mp4

heres my code


local enemy = script.Parent
local hum = enemy.Humanoid

local pathfindingservice = game:GetService("PathfindingService")
enemy.PrimaryPart:SetNetworkOwner(nil)

local function canSeeTarget(target)
	local origin = enemy.HumanoidRootPart.Position
	local direction = (target.HumanoidRootPart.Position - enemy.HumanoidRootPart.Position).unit * 40
	local ray = Ray.new(origin, direction)

	local hit, pos = workspace:FindPartOnRay(ray, enemy)


	if hit then
		if hit:IsDescendantOf(target) then
			return true
		end
	else
		return false
	end
end

local function findtarget()
	local players = game.Players:GetPlayers()
	local maxdist = 50
	local nearesttarget

	for index,player in pairs(players) do
		if player.Character then
			local target = player.Character
			local dist = (enemy.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude

			if dist < maxdist and canSeeTarget(target) then
				nearesttarget = target
				maxdist = dist
			end
		end
	end

	return nearesttarget
end

local function getpath(dest)
	local pathConfig = {
		["AgentHeight"] = 5.25,
		["AgentRadius"] = 2.5,
		["AgentCanJump"] = false
	}

	local path = pathfindingservice:CreatePath(pathConfig)

	path:ComputeAsync(enemy.HumanoidRootPart.Position,dest.Position)

	return path
end



local function attack(target)
	local distance = (enemy.HumanoidRootPart.Position - target.HumanoidRootPart.Position).Magnitude

	if distance > 4 then
		hum:MoveTo(target.HumanoidRootPart.Position)
	else
		if hum.Health > 0 then
			target.Humanoid.Health = 0
		end

	end
end


local function walkto(destination)

	local path = getpath(destination)

	if path.Status == Enum.PathStatus.Success then
		for index, waypoint in pairs(path:GetWaypoints()) do
			local target = findtarget()
			if target and target.Humanoid.Health > 0 then
				print("TARGET FOUND", target.Name)
				attack(target)
				break
			else
				print("Moving to ", waypoint.Position)
				hum:MoveTo(waypoint.Position)
				hum.MoveToFinished:Wait()
			end
		end
	else
		hum:MoveTo(destination.Position - (enemy.HumanoidRootPart.CFrame.LookVector * 10))
	end
end


function patrol()
	local waypoints = workspace.patrolwaypoints:GetChildren()
	local randomNum = math.random(1, #waypoints)
	walkto(waypoints[randomNum])
end

while wait(0.25) do
	patrol()
end

https://www.youtube.com/watch?v=gSYx6MVa9Tc&list=PLtMUa6NlF10ebiP_eMp8Q9AQVo18oggII&index=3 heres the tutorial i used

why does it stutter like this?

Try generating your path, it might be caused by the path-finding itself…

how would I generate a path with pathfinding?


as its locating me it switches back to the path even though it can see me

this bit of your script is causing it to return to the path. Due to the fact that this function is called even IF the player is being chased, your enemy will stutter. Try adding a “chasing” booleon or something along those lines.