Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
2

How does the script know what these are?

Asked by
emite1000 335 Moderation Voter
9 years ago

It was not until today that I finally read and understand how parameters/arguments of functions work. However, I don't understand how they work when the function is declared as it is called. For example:

ClickDetector.MouseClick:connect(function(clicked)
    local Sgui = Instance.new("ScreenGui", clicked.PlayerGui)

The parameter "clicked" is never defined as a value since the function is called then and there. Yet this script will work to make a ScreenGui appear inside the localplayer's PlayerGui. How does it know what "clicked" is?

3 answers

Log in to vote
5
Answered by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
9 years ago

:connect is not a straightforward use of functions -- it isn't using functions like they normally are.

This is a really good question -- this is a weird bit of code, and it's a little disappointing not many learning scripters realize how strange it looks.

I'm going to use the Touched event as in my examples, but it works the same way as the MouseClick event.


First, let's write our connection separately from the definition of the function:

function makeRed( part )
    part.BrickColor = BrickColor.red()
end

workspace.Wall.Touched:connect( makeRed )

part is defined, in the scope of the makeRed function, to be the first value that makeRed is given when called.

First of all, ignoring the :connect line, we can just use makeRed ourselves:

makeRed(workspace.Player1.Torso)
makeRed(workspace.BasePlate)

The first line, part will be the player's Torso; the second line, it will be the BasePlate.


Here's something Lua lets us do. It's called first class functions or higher ordered functions (EDIT: had serious nomenclature typo)

function makeRed( part )
    part.BrickColor = BrickColor.red()
end

function makeBlue( part )
    part.BrickColor = BrickColor.blue()
end

local changer
if math.random(2) == 1 then
    changer = makeRed
else
    changer = makeBlue
end

-- Notice that we did not CALL either makeRed or makeBlue
-- We just used the *function itself* as a *value* (just like
-- I can use variables like `workspace` or `ClickDetector`)

changer( workspace.BasePlate )
-- half the time will be red, half the time will be blue

What happened here? changer now stores the value of a function -- that means when we call changer, it will actually be calling the function we assigned it to, which was either makeRed or makeBlue.


:connect does a similar thing. When you say :connect( makeRed ), you aren't calling makeRed. You're giving the value of makeRed so that ROBLOX can call it later.

Here's a fake implementation of how .Touched:connect( x ) might work:

function connect( xfun )
    while wait() do
        local near = getNearestPart( workspace.Wall )
        if areTouching(near, workspace.Wall) then
            xfun( near ) -- Here!
        end
    end
end

How does it know what [the parameter's value] is?

Somewhere, :connect is calling your function with a parameter -- :connect tells your function what the parameter is, in the same way that functions normally get their parameters





Higher ordered functions are awesome. Here's an aside on the makeBlue and makeRed we had earlier:

function makeColorChanger( str )
    return function(part)
        part.BrickColor = BrickColor.new(str)
    end
end

makeRed = makeColorChanger("Bright red")
makeBlue = makeColorChange("Bright blue")
makeGreen = makeColorChange("Bright green")
-- etc!

-- Let's make the baseplate red:
makeRed( workspace.BasePlate )
-- OR:
makeColorChanger("Bright red")(workspace.BasePlate)
-- Funny looking, but awesome that it works

MouseClick Case

The parameter is the player who clicked. (It isn't the LocalPlayer -- a "Script" object (as opposed to a LocalScript) doesn't have the concept of a LocalPlayer)

ROBLOX obviously can know who clicked it, since the game has to know it was clicked at all (so it just also adds, "it was this guy"). So ROBLOX just informs the event of that information.

0
I understand your answer and how variables can store a function as a value, but as for how that snippit of code I posted works it seems that your answer is just "somwhere somehow it's getting the Localplayer?" (I'm not meaning this as an insult or anything, but is there anyway you can explain [if you know how] it is getting that?) emite1000 335 — 9y
0
It *isn't* the LocalPlayer -- it's the player who clicked. ROBLOX obviously knows who clicked it, since the server has to know it was clicked at all. So ROBLOX just informs the event of that information. BlueTaslem 18071 — 9y
0
(Sorry about the very late response. I didn't realize you added another comment.) So the Event is giving that information to the function? I kind of expanded on this here: https://scriptinghelpers.org/questions/15736/do-events-provide-built-in-arguments emite1000 335 — 9y
0
Correct. The event passes the argument to the function. BlueTaslem 18071 — 9y
Ad
Log in to vote
0
Answered by
Redbullusa 1580 Moderation Voter
9 years ago

Notice in this link that the parameter is playerWhoClicked.

The MouseClick event's parameter returns the player model. This is a built-in feature of this event.

Another such example is the HealthChanged event. The example uses health as the parameter as the value "Health" is changed to.

Truth be told, I don't really know. I pretty much assumed that's how some events behave.

Log in to vote
0
Answered by
emite1000 335 Moderation Voter
9 years ago

Answered in Do Events provide built-in arguments?

Answer this question