Is there a way to force an NPC to look at a part while moving in different directions?

I’ve tried to do this just results in very jittery movement like the poor guy is moving at 5fps

I am really hoping someone will have a solution

here is the code i have so far, it will work if you paste it into any npc (minus the teleportation parts/particles)

local RS = game:GetService("RunService")

task.wait(1)

local attacking = true
local retreating = false

local npc = script.Parent

for i, v in pairs(npc:GetDescendants()) do
	if v:IsA("BasePart") then
		v:SetNetworkOwner(nil)
	end
end

local humanoid = npc:FindFirstChild("Humanoid")
local humRoot = npc:FindFirstChild("HumanoidRootPart")
local torso = npc:FindFirstChild("Torso")

local tpPoints = game.Workspace:FindFirstChild("Map"):FindFirstChild("GuideArena"):FindFirstChild("Points")

function findTarget(pos)
	local list = game.Workspace:GetChildren()
	local closestTarget = nil
	local minDist = 500

	local function choose(theList)
		for _, dummy in ipairs(theList) do
			if dummy:IsA("Model") and dummy ~= script.Parent.Parent then
				local torso = dummy:FindFirstChild("Torso")
				local humanoid = dummy:FindFirstChild("Humanoid")
				local rootPart = dummy:FindFirstChild("HumanoidRootPart")
				if torso and humanoid and humanoid.Health > 0 and rootPart and dummy ~= npc then
					local distance = (torso.Position - pos).Magnitude
					if distance < minDist then
						closestTarget = dummy
						minDist = distance

					end
				end
			end
		end
	end

	choose(list)

	return closestTarget
end

function teleport()
	local points = tpPoints:GetChildren()
	local randomPoint = points[math.random(1, #points)]
	if randomPoint:IsA("BasePart") then
		torso.Warp:Play()
		for i, v in pairs(torso:GetChildren()) do
			if v:IsA("ParticleEmitter") then
				v.Enabled = true
			end
		end
		task.wait(1)
		torso.Thunder:Play()
		npc:PivotTo(randomPoint.CFrame)
		for i, v in pairs(torso:GetChildren()) do
			if v:IsA("ParticleEmitter") then
				v.Enabled = false
			end
		end
	end
end

function chase()
	while true do
		local target = findTarget(humRoot.Position)
		if target then
			local direction = (target.PrimaryPart.Position - humRoot.Position).Unit
			local distanceToTarget = (target.PrimaryPart.Position - humRoot.Position).Magnitude

			if attacking then
				humanoid:MoveTo(target.PrimaryPart.Position + direction)
			elseif retreating then
				humanoid:MoveTo(target.PrimaryPart.Position + direction * -100)
			end

			if distanceToTarget < 10 then
				local chanceToJump = math.random(1, 100)
				if chanceToJump <= 20 then
					humanoid.Jump = true
				end
			end
		end
		RS.Heartbeat:Wait()
	end
end

function switchMode()
	retreating = not retreating
	attacking = not attacking
end

spawn(function()
	chase()
end)

spawn(function()
	while true do
		task.wait(math.random(5, 15))
		teleport()
	end
	
end)

while true do
	task.wait(math.random(5,8))
	switchMode()
	task.wait(math.random(1,2))
	switchMode()
end


here is a video showcasing how he moves around