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

Am I using ":GetChildren()" right or do I have a different problem?

Asked by 6 years ago

I want to make a sink where on the click of a button, it makes water (initally at Transparency = 1) appear (stage1) by changing the Transparency value to ".55". After 10 seconds, more water will appear (stage2), and after another 10 seconds, more water will appear (stage3). This seems like an easy script but I don't know what I'm doing wrong.

local stage1 = game.Workspace.Stage1Water:GetChildren()
local stage2 = game.Workspace.Stage2Water:GetChildren()
local stage3 = game.Workspace.Stage3Water:GetChildren()
function onClick()
    if script.Parent.OnOff.Value == false then
        script.Parent.OnOff.Value = true
        stage1.Transparency = .55
        wait(10)
        stage2.Transparency = .55
        wait(10)
        stage3.Transparency = .55
    else
        script.Parent.OnOff.Value = false
        stage1.Transparency = 1
        stage2.Transparency = 1
        stage3.Transparency = 1

    end
end
script.Parent.ClickDetector.MouseClick:connect(onClick(
))

2 answers

Log in to vote
2
Answered by 6 years ago
Edited 6 years ago

DanzLua is correct, but that isn't your only problem -- you also called onClick when trying to give MouseClick something to connect to. Since onClick doesn't return anything, you effectively told it to connect to nil (or "nothing"). It evaluates like this:

script.Parent.ClickDetector.MouseClick:connect(onClick())
--onClick is called and returns nil, so statement now looks like:
script.Parent.ClickDetector.MouseClick:connect(nil)
--which probably raised an error

To see such errors in the future, be sure to have the Output window open. (The Script Analysis window is also very helpful - if it displays a warning, there is almost always something wrong that you should fix; it can also catch syntax errors before you run the script.)

Below, I show how you might use a function to ensure that you needn't copy/paste code:

local stage1 = game.Workspace.Stage1Water:GetChildren()
local stage2 = game.Workspace.Stage2Water:GetChildren()
local stage3 = game.Workspace.Stage3Water:GetChildren()
function setTransparency(list, transparency)
    for i = 1, #list do
        if list[i]:IsA("BasePart") then -- this 'if' is only needed if some children *aren't* a BasePart
            list[i].Transparency = transparency
        end -- end the 'if'
    end
end
function onClick()
    if script.Parent.OnOff.Value == false then
        script.Parent.OnOff.Value = true
        setTransparency(stage1, .55)
        wait(10)
        setTransparency(stage2, .55)
        wait(10)
        setTransparency(stage3, .55)
    else
        script.Parent.OnOff.Value = false
        setTransparency(stage1, 1)
        setTransparency(stage2, 1)
        setTransparency(stage3, 1)
    end
end
script.Parent.ClickDetector.MouseClick:Connect(onClick)

Note:

  • I've put DanzLua's code in the function setTransparency - as you can see, it's much more efficient than copy pasting the for loop 6 times (instead, we just have to call the function 6 times).
  • connect is deprecated, use Connect instead
  • You could put the different stages in a table and then iterate over them with a for loop (but this isn't necessary and doesn't save any code when you only have 3 stages -- but if you ever end up wanting 4+ stages, it's becomes worth it)

There is another problem with your script - it won't prevent someone from clicking it multiple times. This will mess up the animations. ex, say someone clicks it at "t=0" (let that mean "time of 0"), then stage1 will be semi-transparent at t=0 and stage2 will be semi-transparent at t=10 -- but say someone activates the ClickDetector at t=15 -- then everything will become transparent immediately (which is fine), but your script will then make stage3 semi-transparent at t=20.

There are two fixes:

  1. Use "debounce". Players will not be able to interrupt the animation (so they won't be able to turn it off until it's fully turned on).
  2. Use "call numbers". Players will be able to interrupt the animation at any time. (Whether this is a good thing depends entirely on what you want to do.)

Since you can look up "debounce" examples, I will show you the 2nd option. New script:

local stage1 = game.Workspace.Stage1Water:GetChildren()
local stage2 = game.Workspace.Stage2Water:GetChildren()
local stage3 = game.Workspace.Stage3Water:GetChildren()
function setTransparency(list, transparency)
    for i = 1, #list do
        if list[i]:IsA("BasePart") then -- this 'if' is only needed if some children *aren't* a BasePart
            list[i].Transparency = transparency
        end -- end the 'if'
    end
end
local callNumber = 0
function onClick()
    local thisNumber = callNumber
    callNumber = callNumber + 1
    if script.Parent.OnOff.Value == false then
        script.Parent.OnOff.Value = true
        setTransparency(stage1, .55)
        wait(10)
        if callNumber ~= thisNumber then return end
        setTransparency(stage2, .55)
        wait(10)
        if callNumber ~= thisNumber then return end
        setTransparency(stage3, .55)
    else
        script.Parent.OnOff.Value = false
        setTransparency(stage1, 1)
        setTransparency(stage2, 1)
        setTransparency(stage3, 1)
    end
end
script.Parent.ClickDetector.MouseClick:connect(onClick)

The new code involves the variables callNumber and thisNumber. Quite simply, the function will stop animating if onClick is called during the animation. In the same example I stepped through before, if a user clicks at t=0, pretend callNumber is 3, so thisNumber will also be 3. At t=10, stage2 is semi-transparent (as before). The script then compares callNumber and thisNumber, but doesn't return early because they are still the same. At t=15, the user clicks again and everything becomes semi-transparent -- and callNumber is increased by 1 and is now 4. Thus, at t=20, when the script would normally make stage3 semi-transparent, it instead compares callNumber (4) with thisNumber (still 3) and returns early -- thus, everything remains fully transparent. (In contrast, if you added debounce, the user clicking would do nothing until after t=20, since the animation would still be running.)

0
oh yes, I didn't see the () looked like just calling a function. DanzLua 2879 — 6y
Ad
Log in to vote
1
Answered by
DanzLua 2879 Moderation Voter Community Moderator
6 years ago
Edited 6 years ago

Well when you use :GetChildren() it returns a table, so what you'll want to do is when ever you are doing stage1.Transparency or something like that you want to go through all of the table's values and change their transparency IF its a basepart

for _,v in pairs(stage1) do
    if v:IsA("BasePart") then
        v.Transparency=1
    end
end

Answer this question