I need a script that will adress all the players, not just 1 specific player. So then I can use scripts like
function onTouch() game.Workspace.___.Humanoid.MaxHealth = "0" end script.Parent.Touched:connect(onTouch)
The "___" is where I need the help
To get all of the Players in a Place, you have to use a loop. Specifically, a for
loop. This can be done in two ways, using a numeric or a generic for
. I will show you both, starting with the generic for
:
local Players = game:GetService("Players") --Where Players are stored in the Game script.Parent.Touched:connect() --Anonymous function, since it's only connected once. We don't care who touched it, so no parameter is supplied. for _, v in ipairs(Players:GetPlayers()) do --See below if v.Character then v.Character.Humanoid.Health = 0 end end end)
There is a lot going on in that for
line there, so let me explain it in detail:
The keyword for
designates the rest of the code until the next keyword do
as a loop definition. Basically, it sets up the loop.
In a generic for loop, you give 'parameters' to catch the return
values of an iterator function. , which is called after the in
keyword.
Lua provides two iterator functions out-of-box: pairs
and ipairs
. Both take a Table as an argument, and both return the current Key and current Value for each 'loop', which is why there are two parameters** given. The difference is that pairs
will randomly* traverse the table, visiting each key-value pair once, and then the loop ends, where ipairs
will traverse the table starting at the integer key of 1
, and then of 2
on the next call and so on. ipairs
will not catch non-integer keys, nor will it catch non-sequential integer keys.
*I say randomly, but it's not really random, although it's difficult to ensure it will be the same every time. Basically, the order you see the objects in Explorer is the order pairs
will find them, most of the time.
** Two parameters, but one is just an underscore (_
), which typically (in Lua) means that the value it contains is not used, which it isn't in this case.
After the iterator function call is the do
keyword, which starts the body of the loop. Here I check to make sure the given player has a Character, and then kill it if they do.
The numeric for
is a bit easier to understand:
local Players = game:GetService("Players") script.Parent.Touched:connect() local players = Players:GetPlayers() --Lua is caps sensitive for i = 1, #players do if players[i].Character then players[i].Character.Humanoid.Health = 0 end end end)
The numeric for
has a very specific form:
for (parameter) = (startnumber), (endnumber), (step) do
parameter
is simple the variable that holds the current state of the loop.
startnumber
is the number the loop starts at.
endnumber
is the one it ends at.
step
, which defaults to 1
, is what to add to startnumber
every time the code loops.
If endnumbered is reached, the code will execute with i = endnumber
. However, if it is exceeded the loop will end and not execute again.
If you don't know, #
operator gets the number of key-value pairs in a Tables that have starting-at-one sequential, integer keys. Similar to how ipairs
works. The brackets are used to access the members of the players table in the above code, and this works since GetPlayers
returns a Table with sequential integer keys:
table = {"one", "two", three = 3} print(table[1]) --one print(table[2]) --two print(table[3]) --nil (we only gave the first two values automatic 'keys', the third we explicitly defined) print(table.three) --3 (syntactic sugar for the next line of code. Does not work for 'keys' that start with a number, or *are* a number.) print(table["three"]) --3 print(#table) --2 (the third entry is not a sequential integer key)