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

While Loop duplicating, why?[SOLVED]

Asked by
BryanFehr 133
4 years ago
Edited 4 years ago

Hello everyone! I am creating a simulator game, and there's an area where you "sell" your parts collected for in-game currency! And where if you do not have enough, it clones a GUI to player GUI inside the script, and tweens it to you!

Now, EVERYTHING in this script functions, but, it creates multiple of the GUI if you don't have enough, and does the math function:

player.leaderstats.Collected.Value / 2 + player.leaderstats.BrickBux.Value

more than one time!

I'd like to know how to make this While Loop only execute ONCE, and only be reusable after a specific amount of time! I've tried using the wait() functions in order to make this function, but it doesn't seem to work! My full script (ServerScript)will be listed below my end!

Any and ALL help is appreciated! Thank you, ~BryanFehr

while true do
    local debounce = false
    wait(10)
    script.Parent.Touched:Connect(function(hit)
        local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
        if player and debounce == false then
            debounce = true
            if player.leaderstats.Collected.Value >1 then
                player.leaderstats.BrickBux.Value = player.leaderstats.Collected.Value / 2 + player.leaderstats.BrickBux.Value
                wait(5)
                player.leaderstats.Collected.Value = 0
            else
                local cloneui = script.notenoughparts:Clone()
                cloneui.Parent = player.PlayerGui
                cloneui.Frame:TweenPosition(UDim2.new(0.3, 0,0.3, 0))
                if cloneui.Parent == player.PlayerGui then
                end
                wait(5)
                debounce = false
            end
        end
    end)
end

2 answers

Log in to vote
3
Answered by 4 years ago

I'm assuming you want the part to be touched within the 10 second window and it goes away for a certain amount of time before restarting and doing it again.

I modified it slightly to store the connection inside a variable and to disconnect and reconnect it whenever it loops through.

If you read through my comments in the code you should know what I'm trying to do.

local connection

while true do
    wait(10) --//This is the amount of time before you can touch the part

    local debounce = false
    connection = script.Parent.Touched:Connect(function(hit) --//Store the connection inside the variable "connection"
        local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
        if player and debounce == false then
            debounce = true
            if player.leaderstats.Collected.Value >1 then
                player.leaderstats.BrickBux.Value = player.leaderstats.Collected.Value / 2 + player.leaderstats.BrickBux.Value
                wait(5)
                player.leaderstats.Collected.Value = 0
            else
                local cloneui = script.notenoughparts:Clone()
                cloneui.Parent = player.PlayerGui
                cloneui.Frame:TweenPosition(UDim2.new(0.3, 0,0.3, 0))
                if cloneui.Parent == player.PlayerGui then
                end
                wait(5)
                debounce = false
            end
        end
    end)

    wait(10) --//We have to wait a certain amount of time before disconnecting the event. This will be the amount of time you can touch the part

    connection:Disconnect() --//Disconnects the event
end

I could do more to tell you best practices and those sort of problems with your code but honestly I'm tired and this is what I can do right now.

Hope it works.

1
Worked excellent, thank you for your help! BryanFehr 133 — 4y
0
Also another good prctice is to clone guis locally since server should not know about or touch user interface programmerHere 371 — 4y
0
I would have gone more in depth on those sort of better practices but honestly staying up all night has me beat.. CeramicTile 847 — 4y
Ad
Log in to vote
-2
Answered by
BielNS 40
4 years ago
Edited 4 years ago

First of all, remove the loop "while true do", touched event dont need loop and this may be the reason why its duplicating, second, add value = value + value instead of value = value2 + value

example: brickbux.Value = brickbux.Value + collected.value

or else it will go like this

EX: value1 = 532 value2 = 25

value1 = value2 (25) + value1(25)

and that may be the reason that gui duplicated but money didn't


if anything above wasn't the solution soo the reason is maybe that you ain't checking if there is already a gui at player gui

while true do
        local debounce = false
        wait(10)
        script.Parent.Touched:Connect(function(hit)
            local player = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
            if player and debounce == false then
                debounce = true
                if player.leaderstats.Collected.Value >1 then
                    player.leaderstats.BrickBux.Value = player.leaderstats.Collected.Value / 2 + player.leaderstats.BrickBux.Value
                    wait(5)
                    player.leaderstats.Collected.Value = 0
                else
            --//Checking if there ins't already a gui at the playergui
            if not player.PlayerGui:FindFirstChild(script.notenoughparts.Name) then
                        local cloneui = script.notenoughparts:Clone()
                        cloneui.Parent = player.PlayerGui
                        cloneui.Frame:TweenPosition(UDim2.new(0.3, 0,0.3, 0))
                        if cloneui.Parent == player.PlayerGui then
                        end
                            wait(5)
                        debounce = false
            end
                end
            end
        end)
    end

Answer this question