AI jittering whenever close to an enemy?

Hello, my ai seems to be jittering/shaking a lot whenever it spots an enemy


I feel like these lines of code are the culprit:

				if target and target.HumanoidRootPart then
					local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude

					if distance <= 3 then
						WalkAnim:Stop()
							NPCProperties.target = target
							AI[AttackType](NPCProperties)
					else
						local targetVel = target.PrimaryPart.Velocity
						local leadBy = 7
						local lead
						
						if targetVel.Magnitude < 0.1 then
							lead = Vector3.new(0, 0, 0)
						else
							lead = targetVel.Unit * leadBy
						end
						hum:MoveTo(target.PrimaryPart.Position + lead)
					end
				end

I’ve tried changing the numbers around a bit, editing the code, changing it and more, this code was mostly given to me by a dev forum reply a while back.

Here is my entire (module) script:

local Players = game:GetService('Players')
local RunService = game:GetService('RunService')
local PathfindingService = game:GetService('PathfindingService')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local RaycastHitbox = require(ReplicatedStorage.RaycastHitboxV4)
local maxDistance = math.huge
local Anims = script.Parent.R6Anims

local AI = {}
AI.__index = AI

function AI.new(NPC,WalkAnim,AttackType)
	spawn(function()
		local Team = NPC.Parent.Name
		local NPCProperties = setmetatable({},AI)
		local hum = NPC.Humanoid
		local humrp = NPC.HumanoidRootPart
		local WalkAnim = hum:LoadAnimation(WalkAnim)
		local RunOnce = false
		local MeleeDB = false
		local NPCHitbox = nil

		NPCProperties.NPC = NPC
		NPCProperties.Humanoid = hum
		NPCProperties.humrp = humrp
		NPCProperties.hum = hum
		NPCProperties.NPCHitbox = NPCHitbox
		NPCProperties.MeleeDB = MeleeDB
		NPCProperties.RunOnce = RunOnce
		NPCProperties.Team = Team
		NPCProperties.WalkAnim = WalkAnim
		--Pathfinding
		NPC.PrimaryPart:SetNetworkOwner(nil)
		local CoreOfFactory = workspace.CentreOfFactory

		local function findTarget()
			local team
			if Team == 'Allies' then
				team = workspace.Enemies:GetChildren()
			else
				team = workspace.Allies:GetChildren()
			end
			local MaxDistance = 200
			local nearestTarget

			for _,enemy in pairs(team) do
				if enemy then
					if enemy.Humanoid.Health > 0 then
						local target = enemy
						local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude

						if distance < MaxDistance then
							nearestTarget = target
							MaxDistance = distance
						end
					end
				end
			end

			return nearestTarget
		end

		local function agro()
			repeat task.wait(0.05)
				local target = findTarget()

				if target and target.HumanoidRootPart then
					local distance = (humrp.Position - target.HumanoidRootPart.Position).Magnitude

					if distance <= 3 then
						WalkAnim:Stop()
							NPCProperties.target = target
							AI[AttackType](NPCProperties)
					else
						local targetVel = target.PrimaryPart.Velocity
						local leadBy = 7
						local lead
						
						if targetVel.Magnitude < 0.1 then
							lead = Vector3.new(0, 0, 0)
						else
							lead = targetVel.Unit * leadBy
						end
						hum:MoveTo(target.PrimaryPart.Position + lead)
					end
				end
			until target == nil or target.Humanoid.Health == 0 or (humrp.Position - target.HumanoidRootPart.Position).Magnitude > maxDistance
		end

		local function walkToCore()
			local path = PathfindingService:CreatePath()

			local success, errorMessage = pcall(function()
				path:ComputeAsync(humrp.Position, CoreOfFactory.Position)
			end)
			WalkAnim:Play()
			if success and path.Status == Enum.PathStatus.Success then
				local waypoints = path:GetWaypoints()
				for _,waypoint in pairs(waypoints) do

					if waypoint.Action == Enum.PathWaypointAction.Jump then
						hum:ChangeState(Enum.HumanoidStateType.Jumping)
					end

					if findTarget() and (humrp.Position - findTarget().HumanoidRootPart.Position).Magnitude < maxDistance then
						agro()
					end

					hum:MoveTo(waypoint.Position)
					hum.MoveToFinished:Wait()
				end
			end
			WalkAnim:Stop()
		end

		walkToCore()
	end)
end

function AI.Melee(metatable)
	local self = metatable
	if self.MeleeDB == false then
		self.MeleeDB = true
		self.WalkAnim:Stop()
		self.NPC:SetPrimaryPartCFrame(CFrame.new(self.NPC.HumanoidRootPart.Position,self.target.HumanoidRootPart.Position))
		local AttackAnim = self.hum:LoadAnimation(Anims.Attack)
		local Damage = 15
		local delay = 1
		
		if self.RunOnce == false then
			self.RunOnce = true
			self.NPCHitbox = RaycastHitbox.new(self.NPC['Right Arm'])
			self.NPCHitbox:SetPoints(self.NPC['Right Arm'],{Vector3.new(0,0,1),Vector3.new(-1,1,3),Vector3.new(-3.5,1,3)})
		end

		AttackAnim:Play()
		self.NPCHitbox:HitStart()

		self.NPCHitbox.OnHit:Connect(function(hit,humanoid)
			if humanoid.Parent.Name ~= self.NPC.Name and not humanoid:FindFirstAncestor(self.Team) then
				humanoid:TakeDamage(Damage)
			end
		end)
		coroutine.wrap(function()
			AttackAnim.Stopped:Wait()
			self.NPCHitbox:HitStop()
			task.wait(delay)
			self.MeleeDB = false
			self.WalkAnim:Play()
		end)()
	end
end



return AI

I feel like this post died… (char)

In Summary:

  • Reduce how often the AI checks and updates its movement towards the target to avoid frequent adjustments.
  • Smooth the rotation towards the target to prevent sudden changes in direction.
  • Adjust the leading factor to avoid over-predicting the target’s position.
  • Limit the speed at which the NPC changes direction or adjusts its velocity.

If the issue persists, I’d recommend adding debug print statements to track the NPC’s position, target position, and velocity during gameplay to better understand what is causing the jitter. Let me know if you need further clarification or assistance!