Npc script help

So Im making an npc that chase players and if theres no one around him he walks to random parts on the map. The problem is when I test it by Play in roblox studio npc is kinda lagging/glitching but if I test it by Run without playing npc is moving correctly.

local pfs = game:GetService("PathfindingService")
local RS = game:GetService("RunService")
local dummy = script.Parent
local distanceThreshold = 50
local spotDistanceThreshold = 22

local debounce = false
local movetoFinished = true

local debur = false

local dummy = script.Parent

local wa = script.RunAnim:Clone()
local walkAnimation = dummy:WaitForChild("Humanoid"):LoadAnimation(wa)
walkAnimation:Play()


dummy.Humanoid.MoveToFinished:Connect(function()
	movetoFinished = true
end)


local function getDistance(point1, point2)
	return (point1 - point2).magnitude
end

local function playAnim(animId, name)
	local ntcz = false
	local x = dummy.Humanoid.Animator:GetPlayingAnimationTracks()
	for _, track in ipairs(x) do
		if track.AnimationId ~= animId then
			track:Stop()
			track:Destroy()
			ntcz = true
		end
	end
	
	if ntcz == true then
		local humanoid = dummy:WaitForChild("Humanoid")
		local inst = Instance.new("Animation")
		inst.Name = name
		inst.AnimationId = animId
		local Animation = humanoid:LoadAnimation(inst)
		Animation.Looped = true
		Animation:Play()
	end
end

local idle = script.Parent.Animate.idle:WaitForChild("Animation1")
local run = script.Parent.Animate.run:WaitForChild("RunAnim")

local leatestsSpot = {0, 0, 0}

RS.Heartbeat:Connect(function()
	if debounce == false then
		debounce = true
		local distances = {}
		local anyPlayerInDistance = false
		for _, player in game.Players:GetPlayers() do
			if player.TeamColor == BrickColor.new("Medium brown") then
				if player.Character.Humanoid.Health > 0 then
					local hmru = player.Character:FindFirstChild("HumanoidRootPart")
					local distance = 999999999
					if hmru then
						distance = getDistance(dummy.HumanoidRootPart.Position, hmru.Position)
					end

					local playerPos = player.Character.HumanoidRootPart.Position

					if distance <= distanceThreshold then
						local tableSkeleton = {userId = player.UserId, dist = distance}
						table.insert(distances, tableSkeleton)
						anyPlayerInDistance = true
					end
				end
			end
		end

		if anyPlayerInDistance == true then
			local minValue = 99999999999
			local plrId = nil
			for _, value in ipairs(distances) do
				if minValue > value.dist then
					plrId = value.userId
				end
			end

			if plrId then
				local player = game.Players:GetPlayerByUserId(plrId)

				local path = pfs:CreatePath()
				path:ComputeAsync(dummy.HumanoidRootPart.Position,player.Character.HumanoidRootPart.Position)
				for _, waypoint in pairs(path:getWaypoints()) do
					dummy.Humanoid:MoveTo(waypoint.Position)
					dummy.Humanoid.MoveToFinished:Wait()
				end
				path:Destroy()
			end
		else
			local avaliableSpots = {}

			for _, spot in game.Workspace.Sewers.RandomSpots:GetChildren() do
				if spot:IsA("Part") then
					local distance = getDistance(dummy.HumanoidRootPart.Position, spot.Position)

					if distance <= spotDistanceThreshold then
						table.insert(avaliableSpots, spot.Name)
					end
				end
			end

			if #avaliableSpots > 0 then
				print("avaliable = "..#avaliableSpots)
				local spot = nil
				local brek = false
				repeat
					wait()
					local x = math.random(1, #avaliableSpots)
					print(x)
					spot = avaliableSpots[x]

					local isInLeatest = false
					for numi, valiu in ipairs(leatestsSpot) do
						if valiu == spot then
							isInLeatest = true
						end
					end
					if isInLeatest == true then

						local spotsLeft = 0
						for i, value in ipairs(avaliableSpots) do
							spotsLeft += 1
						end

						if spotsLeft <= 1 then
							brek = true
						else
							table.remove(avaliableSpots, x)
						end
					else
						brek = true
					end
				until brek == true
				table.remove(leatestsSpot, 1)
				table.insert(leatestsSpot, spot)

				local path = pfs:CreatePath()
				path:ComputeAsync(dummy.HumanoidRootPart.Position, game.Workspace.Sewers.RandomSpots:FindFirstChild(spot).Position)

				for _, waypoint in pairs(path:getWaypoints()) do
					dummy.Humanoid:MoveTo(waypoint.Position)
					dummy.Humanoid.MoveToFinished:Wait()
				end
				path:Destroy()
			end
		end
		debounce = false
	end
end)

Any ideas how to fix it or any other way to make good npcs?

2 Likes

if its laggy try
Humanoid:SetNetworkOwnership(nil)
This means the server will now run the humanoid stopping the choppy movement, (However walkspeeds below 1 or above 60 may start to lag)

1 Like