How does this code work?

I have two codes that I want to make sure I understand correctly. I can give you the full scripts if you really feel like they are not complete and missing out on something for you to answer my questions.

Please don’t unnecessarily complicate your answers. I am happy to see and learn new terminology, as long as it is actually useful and is used in a meaningful manner. Thank you!

  1. I am not sure how does the code here knows exactly that the “touchedPart”, the first parameter of the function, is the part of a character?. Does this have to do something with the colon passing the “Players” as the first parameter in the second line?
local function onTouched(touchedPart)
local player = game.Players:GetPlayerFromCharacter(touchedPart.Parent)
-- Some code
end
  1. Same thing here. I don’t understand how the code knows that the “player” argument is actually the player that is in the game. Does it have to do with passing PlayerAdded as the first parameter when you connect the function? (Also, would it be more accurate to say the player client instead of just the player?)
local PlayerAdded(player: Player)
-- Some code
end

game:GetService("Players").PlayerAdded:Connect(PlayerAdded)
1 Like

you have to use

if player then

it’s equivalent to

if player ~= nil then

It is not sure, it tries to check that and usually there should be an if to see if the player exists or not.

PlayerAdded is pretty straight forward. It gives you the player that joined the game. Always.

Doesn’t matter, really, but “Player” is more commonly used.

3 Likes

The fact is that when you implement a function in Connection, all arguments are automatically passed to it.

Let’s look at an example of code that is used most often

game.Players.PlayerAdded:Connect(function(Player) -- Player is the built-in argument of this connection
   -- Function
end)

Pay attention to the “function” column, we simply create a new function without variables (built-in function), that is,

game.Players.PlayerAdded:Connect(function(Player)
   -- Function
end)

this option

local function PlayerAdded(Player)
   -- Function
end

game.Players.PlayerAdded:Connect(PlayerAdded)

and this option are identical.
We simply changed the position of the function in the code.

1 Like

Let’s break it down:

  1. onTouched(touchedPart): In Roblox, the Touched event fires when a part comes into contact with another part. The argument touchedPart is the part that came into contact with the part where the event is connected. When you use game.Players:GetPlayerFromCharacter(touchedPart.Parent), you’re trying to get the player who owns the character that the touchedPart belongs to. If touchedPart is part of a character model (like a limb), touchedPart.Parent would be the character model, and GetPlayerFromCharacter would return the player who owns that character. If touchedPart is not part of a character model, GetPlayerFromCharacter would return nil.
  2. PlayerAdded(player: Player): In Roblox, the PlayerAdded event fires when a player enters the game. The argument player is the player who just entered. When you connect a function to this event with game:GetService("Players").PlayerAdded:Connect(PlayerAdded), that function will be called whenever a new player enters the game, and the new player will be passed as the argument to the function. So in this case, player is indeed the player that just entered the game.

In both cases, it’s not so much about “passing” parameters as it is about how events work in Roblox. When an event fires, it provides certain information (like which part was touched or which player was added), and you can use that information in your functions by accepting it as arguments.

1 Like

I think I understand now how it works, but the problem is that in my code example that I am looking at it doesn’t seem to have the onTouched function connected to a Touched event. Is it possible for the code to know that the touchedPart is the part of the player that touched something without the Touched event? I think this is where I am mainly confused. Maybe the YouTuber that I took the code from just didn’t show the code line where he connects the function to the Touched event?

Also, is that so that any other argument after the first argument player:Player is seen by the code as nil since the player client is set only to the first argument it meets? (Given that we don’t define other arguments as anything)

local PlayerAdded(player: Player)
-- Some code
end

game:GetService("Players").PlayerAdded:Connect(PlayerAdded)

I’d definitely recommend you check out a few documentation posts as you go through whatever tutorials you decide to check out.

This documentation for the Touched event in relation to two BaseParts touching shows that there is a parameter being passed called otherPart.
This sample code:

game.Workspace.Part.Touched:Connect(function(otherPart)
    print("Touched " .. otherPart.Name)
end)

Is relatively the same as this code here:

local function onTouched(touchedPart)
    print("Touched " .. touchedPart.Name)
end

game.Workspace.Part.Touched:Connect(onTouched)

Both of these snippets will produce the same outcome, which is printing to the console “Touched [name of part]”.

These are built-in events, which in this case, when two parts touch each other the Touched event is fired and the parameter otherPart is also passed along with it. In the function that you connect it to, like onTouched, you can rename that parameter to be anything you want, like touchedPart.

In summary, roblox is giving us the other part that was touched with no extra work on our end, that’s what built-in events are and there are many more for you to find out and have fun with, they are essential to roblox developing.

To go onto the topic of this:

local PlayerAdded(player: Player)
-- Some code
end

game:GetService("Players").PlayerAdded:Connect(PlayerAdded)

This code should really be reformatted to look like this for best practice and to fix that function mistake:

local Players = game:GetService("Players")

local function onPlayerAdded(player)
    -- Some code
    -- ex: print(player.Name) -- This would be the player who just joined the game
end

Players.PlayerAdded:Connect(onPlayerAdded)

player: Player is optional here in my opinion since that is what’s called type checking. You aren’t going to need type checking quite yet but feel free to make it a habit if you so please.

This is another built-in event of the Players Service. Services are something you should also get familiar with possibly using the documentation, or even looking up a tutorial specifically related to them but they are fairly straightforward.

All you have to know for this is every time a player joins, the PlayerAdded event is fired as a part of the Players Service, so when you want to do something when a player joins, that’s your built-in event.

I hope this helped out and I tried not to use too much complicated terminology, feel free to ask more questions of course!

1 Like

Note: I made a comprehensive explanation at the bottom.
An argument is a parameter for a function and passing arguments is passing parameters to a function.
1:

local function onTouched(touchedPart) -- touchedPart is the argument
 local player = game.Players:GetPlayerFromCharacter(touchedPart.Parent)
 if not player then -- :GetPlayerFromCharacter() returns nil if the argument passed is NOT a player. Keep in mind nil is also false in Roblox programming which makes this valid.
  return -- return nil if no player
 end
 -- Some code
end

-- Pretend examplePart is some part
examplePart.Touched:Connect(onTouched) -- I assume :Connect() passes arguments to non-anonymous functions

2:

local PlayerAdded(player: Player) -- Ditto.
-- Some code
end

game:GetService("Players").PlayerAdded:Connect(PlayerAdded) -- Passes over argument.

Keep in mind you can’t pass arguments to an event without any arguments to pass.

If you don’t understand how :Connect() works, here’s an example:

-- This code demonstrates how events work
local touched = script.Parent.Touched -- Touched is an event, it activates or fires when it touches something

touched:Connect(function() -- :Connect() is responsible for running a specific function once the event is fired.
 print("Part has been touched!") -- When touched, print this
end)

--[[
Think about it like this, events are essentially signals, i.e if part touched, send a signal.
Each instance has different events, 
the touched event doesn't work for example GUI elements.

:Connect() is responsible for putting those signals in use.
Any functions placed inside the parentheses will be ran if the signal or event fires, including anonymous
functions.

You can either pre-define a function and place it within the parentheses, or create
an anonymous function, which was shown above. The function has no name and is not pre-defined,
hence the term "anonymous function".

:Connect() can also send data to the function *if* the function has any arguments.
This is demonstrated below:
]]

touched:Connect(function(otherPart)
 print("The part that had been touched: " .. otherPart.Name)
end)

--[[
Because the Touched signal or event preferrably we would call it 
has 1 argument to pass, we are able to put 1 argument in the function 
which essentially *returns* the other part that had been touched.

There's a difference between returning it and simply printing it.
i.e it works like this:
]]

-- For the sake of example
local function return1()
 return 1
end)

local function print1()
 print(1)
end)

--[[
 The difference is that our function return1() would only *return* 1, which is more useful than simply printing it.

Returning in functions essentially means it outputs data when used. We're allowed to do print(return1()) because return1() outputs the number 1.

We're perfectly able to do return1() + return1(), because both functions output a number which arithmetic operations are able to be performed on.
On the other hand, print1() however returns nothing and merely prints. If it returns nothing, it returns nil.

print1() + print1() would definitely not be possible because you're trying to do an arithmetic operation on nil (throwing an error).

Outputs are different than print(). Print is outputs to the *console*, outputs are outputs period.
]]

About time I got that out there.

1 Like

In Roblox Lua, the Touched event is used to detect when a part comes into contact with another part. The Touched event passes the otherPart that was touched to the connected function. Here’s an example:

local function onTouched(otherPart)
    local player = game.Players:GetPlayerFromCharacter(otherPart.Parent)
    if player then
        print(player.Name .. " touched the part")
    end
end

part.Touched:Connect(onTouched)

In this example, onTouched is a function that takes one argument, otherPart. When the part is touched, this function is called with otherPart being the part that touched it. Inside the function, we use GetPlayerFromCharacter to get the player who owns the character that touched the part.
Collisions | Documentation - Roblox Creator Hub

Regarding your second question, in Lua, if you don’t provide a value for an argument in a function call, it will be nil. So yes, any other argument after the first argument player:Player would be seen as nil if you don’t define them as anything.

Your code snippet is connecting to the PlayerAdded event of the Players service. This event fires when a player enters the game. The connected function PlayerAdded takes one argument, which is the player who joined. If you were to add more arguments to this function without passing them in when calling it, they would be nil.

local function PlayerAdded(player: Player)
    -- Some code
end

game:GetService("Players").PlayerAdded:Connect(PlayerAdded)

In this code, when a player joins the game, the PlayerAdded function is called with the player who joined as its argument.
Players | Documentation - Roblox Creator Hub

3 Likes

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.