Pathfinding waypoints help

The npc keeps twitching when they are turning corners.
Video showing that :

  1. I don’t want the waypoints to stick to the wall
  2. The npc starts to twitch around corners

The script is here (line 97 is where the pathfinding stuff is):

local npcTag = "StandardBroccoli"

local CollectionService = game:GetService("CollectionService")
local RunService = game:GetService("RunService")
local PathfindingService = game:GetService("PathfindingService")
local TweenService = game:GetService("TweenService")
local ServerStorage = game:GetService("ServerStorage")

local NPCFunctions = require(ServerStorage.NPCFunctions)
local DamageModule = require(ServerStorage.DamageModule)
local EffectModule = require(ServerStorage.EffectsModule)

local function visualise(pos)
	local p = Instance.new("Part")
	p.Anchored = true
	p.CanCollide = false
	p.Size = Vector3.new(1, 1, 1)
	p.Position = pos
	p.Color = Color3.new(0, 1, 0)
	p.Parent = workspace
	game:GetService("Debris"):AddItem(p, 5)
end

local function HandleNPC(npc)
	local humanoid: Humanoid = npc:FindFirstChild("Humanoid")
	local root: BasePart = npc:FindFirstChild("HumanoidRootPart")
	local neck: Motor6D = npc:FindFirstChild("Torso").Neck

	local originalNeckC0 = neck.C0

	if root:IsDescendantOf(workspace) then
		for _, part in pairs(npc:GetDescendants()) do
			if part:IsA("BasePart") then
				part:SetNetworkOwner(nil)
			end
		end
	end
	if not humanoid or not root then
		warn("NPC missing Humanoid or Root part: " .. npc.Name)
		return
	end

	local statsFolder = npc:FindFirstChild("Statistics")
	if not statsFolder then
		warn("NPC missing Statistics folder: " .. npc.Name)
		return
	end

	local npcStats = {
		TargetDistance = statsFolder:WaitForChild("TargetDistance").Value,
		StopDistance = statsFolder:WaitForChild("StopDistance").Value,
		Damage = statsFolder:WaitForChild("Damage").Value,
		AttackDistance = statsFolder:WaitForChild("AttackDistance").Value,
		AttackCooldown = statsFolder:WaitForChild("AttackCooldown").Value
	}
	local lastAttack = tick()

	task.spawn(function()
		while humanoid and humanoid.Health > 0 do
			for _, stat in pairs(statsFolder:GetChildren()) do
				if stat:IsA("NumberValue") or stat:IsA("IntValue") then
					npcStats[stat.Name] = stat.Value
				end
			end
			task.wait(0.1)
		end
	end)

	local animator: Animator = humanoid:WaitForChild("Animator")
	local animations = npc:WaitForChild("Animations")
	local idleAnimation = animations:WaitForChild("Idle")
	local walkingAnimation = animations:WaitForChild("Walking")
	local attackAnimation = animations:WaitForChild("Attack")

	local idleTrack = animator:LoadAnimation(idleAnimation)
	local walkingTrack = animator:LoadAnimation(walkingAnimation)
	local attackTrack = animator:LoadAnimation(attackAnimation)

	idleTrack:Play()

	local function UpdateNPCBehavior()
		local attackingTag = npc:FindFirstChild("AttackingTag").Value 

			local nearestNPC, distance, position = NPCFunctions.findNearestNPCWithTag(npc, attackingTag)
			local modelSize = npc:GetExtentsSize()
			local agentRadius = modelSize.X

			local agentParams = {
				AgentRadius = agentRadius,
				AgentHeight = modelSize.Y,
				AgentCanJump = false
			}

			if nearestNPC and distance < npcStats.TargetDistance and distance > npcStats.StopDistance and nearestNPC.Humanoid.Health > 0 then
				local path = PathfindingService:CreatePath(agentParams)

				path:ComputeAsync(root.Position, nearestNPC:GetPivot().Position)

				if path.Status == Enum.PathStatus.Success then
					TweenService:Create(neck, TweenInfo.new(.25, Enum.EasingStyle.Sine), {C0 = originalNeckC0}):Play()
					local waypoints = path:GetWaypoints()

					if not walkingTrack.IsPlaying then
						walkingTrack:Play()
					end
					for _, waypoint: PathWaypoint in ipairs(waypoints) do
						visualise(waypoint.Position)
						humanoid:MoveTo(waypoint.Position)
						while not humanoid.MoveToFinished do
							task.wait()
						end
						task.wait()
					end

				elseif path.Status == Enum.PathStatus.NoPath then
					NPCFunctions.lookat(position, root, distance, neck)
					humanoid:MoveTo(root.Position)
					walkingTrack:Stop()
				end
			elseif (nearestNPC and (distance <= npcStats.StopDistance or distance > npcStats.TargetDistance)) then
				NPCFunctions.lookat(position, root, distance, neck)

				humanoid:MoveTo(root.Position)
				walkingTrack:Stop()
				if not nearestNPC then
					humanoid:MoveTo(root.Position)
					walkingTrack:Stop()
				end
			end

			if nearestNPC and distance <= npcStats.AttackDistance and tick() - lastAttack >= npcStats.AttackCooldown then
				lastAttack = tick()
				if humanoid and humanoid.Health > 0 and nearestNPC:FindFirstChild("Humanoid") and nearestNPC.Humanoid.Health > 0 then
					NPCFunctions.lookat(position, root, distance, neck)
					TweenService:Create(root, TweenInfo.new(.4, Enum.EasingStyle.Sine), {CFrame = CFrame.lookAt(root.Position, Vector3.new(nearestNPC.PrimaryPart.Position.X, root.Position.Y, nearestNPC.PrimaryPart.Position.Z))}):Play()
					task.wait(.1)
					attackTrack:Play()
					task.defer(function()
						DamageModule:Hurt(nearestNPC, npcStats.Damage, npc.Name)
					end)
				end
			end

	end

	RunService.Heartbeat:Connect(function()
		task.wait(.1)
		if humanoid.Health > 0 then
			task.wait(0.2)
			UpdateNPCBehavior()
		else
			npc:Destroy()
		end
	end)
end

local function BindNPCsWithTag(tag)
	for _, npc in pairs(CollectionService:GetTagged(tag)) do
		print("Binding NPC: " .. npc.Name)
		HandleNPC(npc)
	end

	CollectionService:GetInstanceAddedSignal(tag):Connect(function(npc)
		print("New NPC added: " .. npc.Name)
		HandleNPC(npc)
	end)
end

BindNPCsWithTag(npcTag)