Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
COMMUNITY QUESTION

More effective way to do this? (While loops)

Hi there, i know using infinite while () loops isn't a good idea but I'm not sure how else I'd go about doing this with the desired effect?

Script:

while wait() do 
	local distance = 10
	for _, v in pairs (game.Workspace:GetChildren()) do
		if v:IsA("Model") and v.Name ~= "Dummy" then
			for _, npc in pairs (NPCs:GetChildren()) do
				if npc:IsA("Model") and npc:FindFirstChild("Humanoid").Health > 0 then
					local humanRP = v:WaitForChild("HumanoidRootPart")
					if (npc.HumanoidRootPart.Position - humanRP.Position).magnitude < distance then
						npc.Humanoid:MoveTo(humanRP.Position)
					end
				end
			end
		end
	end
end

Thanks,

3 comments

0

What is this trying to do?

0

It's an NPC that chases the player if they are within the "distance"

0

Using events can sometimes be a great replacement for loops.

1 answer

ack, I see this all the time on this website. thankfully your question is about optimization so I’m glad to explain: never ever use while wait() do (with an empty wait). this is because by using RunService you can go way faster and wait only reaches like 1/30 a second tops even if you put a number like wait(0.000001). rookie mistake.

next, you said infinite while loops are bad. that’s not always the case, RunService does exist for a reason, but for an AI scanning for every player, that can definitely get pretty laggy. then again, it depends on how many enemies you will have. if it is one enemy you can even check multiple times a second, if it’s a horde you will have to tone it down. however your current loop is probably way too fast, personally I would only do 0.1 seconds tops if it was one enemy and the game was singleplayer. so use a longer wait().

next, never ever use for ... in pairs(workspace). I doubt you want to check EVERY single object in the game. here are the steps you should take:

  1. loop through game.Player:GetPlayers()
  2. on each player use player:GetDistanceFromCharacter(enemy)
  3. make sure that the distance is smaller the max distance otherwise ignore
  4. get the shortest of these distances
  5. move there

This discussion is preserved as it was. New answers, comments, and votes are closed.