UI Close after another opens

2021-10-05 20-58-30 I am getting that error.

okay wait,

This text will be hidden

I can send you a RBLX Model of two of my UI’s just so you can test on it? Do you wanna do that?

oh okay,

This text will be hidden

Okay.rbxl (50.7 KB)

script.Parent.MouseButton1Click:Connect(function()
    for _, v in pairs(script.Parent.Parent.Parent:GetChildren()) do
        if v:IsA("Frame") then
            for _, nV in pairs(v:GetChildren()) do
                if nV:IsA("TextButton") then
                    for _, v2 in pairs(nV:GetChildren()) do
                        if v2:IsA("Frame") then
                            local frame = v2
                            frame.Visible = not frame.Visible
                        end
                    end
                end
            end
        end
    end
    script.Parent.Frame.Visible = not script.Parent.Frame.Visible 
end)

before i try that, can you test if this will work?

Sadly nope

oh okay, wait.

This text will be hidden

I made a system that did this awhile ago, basically it works by putting every frame into a table, then checking if each frame was open, if the frame was open, then close it. I also put an ObjectValue whose name is “ToggleButton” in each frame to signify what button should toggle the UI, something like this should work, can’t test rn so there might be errors so let me know and I’ll help you debug:

local uis = {}

local function toggleUI(targetFrame)
    uis[targetFrame] = not uis[targetFrame]
    if not uis[targetFrame] then
        uis[targetFrame].Visible = false
    else
        for i,v in pairs(uis) do
            if v and i ~= targetFrame then -- if the frame is open, close it and set its value to false inside of the uis table, and ensure that you aren't toggling targetFrame
                uis[i] = false
                i.Visible = false
            end
        end
        v.Visible = true
    end
end

for i,v in pairs(script.Parent:GetChildren()) do -- iterate through all the frames, assuming script's parent is the goal ScreenGui
    if v:IsA('Frame') then -- if it's a frame, just to ensure no instance that isn't a frame is being assigned to the value
        uis[v] = false -- set the frame to be false to indicate the UI isn't open
        local toggleButton = v:FindFirstChild('ToggleButton')
        if not toggleButton or not toggleButton.Value then -- if the ToggleButton value isn't found inside of the frame or a value isn't assigned to ToggleButton then,
            warn('No ToggleButton in',v)
            continue
        end
        toggleButton.Value.MouseButton1Click:Connect(function() -- this is where the magic happens, call the toggleMenu function and pass the current iteration's frame
            toggleMenu(v)
        end)
    end
end

Where exactly would I put the script?

Inside the ScreenGui. It also makes the assumption that you have one frame for each UI element

I assume the ScreenGui called Main?

Yeah probably. It’s also only going to work if you have one ScreenGui that contains each frame.

Do you have any time to go on discord and help explain this some more? I’m not very clear

I don’t really wanna give out my discord but if you have one ScreenGui that has every single frame that you only want to have 1 of on screen at a time, it should work assuming the script is a direct child of said ScreenGui.

Yea man I’m lost, sorry. With the current script I have right now to open it, I would have to have that frame in that TextButton for it too open.

For me I use this method even though it’s long its well executed

local but = script.Parent
local frame = script.Parent.Parent
local main = script.Parent.Parent.Parent:FindFirstChild("Main")
local shopGui = script.Parent.Parent.Parent.Parent:WaitForChild("Shop")
local sfx = script.Parent.clicksfx
local sfx2 = script.Parent.hoversfx

but.MouseEnter:Connect(function()
	sfx2:Play()
end)


but.MouseButton1Click:Connect(function()
	
	if frame.Visible == true then
		frame.Visible = false
		
		main.Visible = true
		shopGui.Code.Visible = false
		shopGui.CodeButton.Visible = true
		shopGui.ShopButton.Visible = true
		shopGui.Shop.Visible = false
		sfx:Play()
	else
		frame.Visible = true
		main.Visible = false
	end
end)

When I open a frame: The frame.visible is set to true
then the other frames will be frame.visible set to false.

I’ll try to give you an idea:

> PlayerGui
    > ScreenGui
        > LocalScript that contains the UI visibility controller which is the code sample I wrote for you
        > Frame1
            > ObjectValue that represents what button should toggle Frame1
        > Frame2
            > ObjectValue that represents what button should toggle Frame2
        > Frame3
            > ObjectValue that represents what button should toggle Frame3
        etc...


Like that?
If you really want, I can send you my game file to my UI.

Yeah, it doesn’t have to be called “Frame1” but yes, that’s basically what it is.

Also if you have your ObjectValue’s name as “Value” you should probably change my code sample a bit, particularly the line that finds the ObjectValue:

local toggleButton = v:FindFirstChild('Value')