:GetPlayers not updating properly inside my program

To preface this I just want to apologize if the code seems a little long or overly-complicated for what its trying to achieve, I’m still very new to lua and a lot of this is confusing for me.

I’m making an RPG game from scratch and one of the scripts that I made checks to see how many studs away a player is from an NPC to determine if it should chase them or not; I have yet to script the actual chasing/retreating part yet, since the program seems to only track the distance of one player at a time, rather than all of the players at once.

I’ve noticed that the code within the function distanceCheck() tracks every player in a server if you single it out and run it as is in a loop, and I’ve also noticed that if the first player that joined the server leaves, then the program starts tracking the distance from the second player that joined the server.

--Modify variables below for balancing
local attackRange = 15
local outOfRange = 30
local timeBetweenChecks = .1
--End of custom variables
local chase = false
local retreat = false

local function main()

	--[HELP] This is the part of the code that doesn't work
	local function distanceCheck()
		for i, player in pairs(game.Players:GetPlayers()) do
			print(player:DistanceFromCharacter(script.Parent.Parent.Parent.enemySpawn.Position))
			return player:DistanceFromCharacter(script.Parent.Parent.Parent.enemySpawn.Position)
		end
	end

	--NPC begins chasing the player if this function is called, and it continues to run until the NPC is killed or walked far enough away from
	local function retreatCheck()
		while chase == true do
			wait(timeBetweenChecks)
			print("Within attack range")
			if distanceCheck() >= outOfRange then
				retreat = true
				chase = false
			end
		end
	end

	--Continous loop that checks if the NPC should return back to its spawnpoint; If it is in spawn it will check distances until something enters aggro radius
	while true do 
		if retreat == true then
			print("Player has left attack range")
			retreat = false
		end

		while retreat == false and chase == false do
			wait(timeBetweenChecks)
			if distanceCheck() <= attackRange then
				chase = true
				retreatCheck()
			end
		end
	end    
end

--Disables this script until a player connects and fully loads into the game
game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:wait()
	main()
end)

The issue is that you’re returning inside the loop:

Returning in a loop automatically stops it.


If you want to get the value for all of the players, I recommend creating a table and returning the table, then check all of the values in the table:

-- example
local t = {} -- table to be returned

for _, v in ipairs(table) do
   if condition then -- you don't have to do an if-condition; this is just here for the example
      table.insert(t, v) -- inserts the 'v' value into the table
   end
end

return t -- returns the table
--============================= ANOTHER SCRIPT/CODE
for k, value in ipairs(returnTable) do -- loop through the returned table
   --... do things with the values
end
--===================================================
3 Likes

You may have to reengineer your script a bit. like @HugeCoolboy2007 said their post, returning will break the loop and return to the line proceeding it.

Instead of looping like this, (which can cause performance issues…) create a radius around the NPC that checks for other humanoids, excluding any other NPCs to prevent interference. (e.g. An empty folder in every NPC called “NPC” to distinguish NPCs from actual players.)

1 Like