Quicker Method for scripting multiple Guis

This is pretty simple to understand and is somewhat obvious, but I didn’t realize until it was pointed out, so I’m hoping to similarly help someone.

When making multiple guis, the best way (I’m aware of) to go about the coding of them is by putting them in groups based on function, and the looping through those groups.

For example, lets say you have 4 text buttons that, when activated, all open a different frame.

image
instead of coding for each one individually, you can do this:

  1. Parent all the things you want to code into separate frames based on their function. (I’d recommend making the frames the full size of the screen, to preserve position) Make sure to make the frames’ background transparency 1. Also rename the frames to reflect the function of their contents.
    image

  2. The set up is finished, so now we can get coding. Make a local script in Starter Player Scripts (or in your desired location.)

  3. Then define the player’s screen gui, and the parent frames.

local player = game.Players.LocalPlayer
local ScreenGui = player.PlayerGui:WaitForChild("ScreenGui")
local ThingsBeingOpened = ScreenGui.ThingsBeingOpened
local Openers = ScreenGui.Openers
  1. Here comes the fun part :wink: We loop through all the children of the the Openers frame, (which coincidentally happen to be text buttons :thinking:) and then make a function that runs on their ‘activated’ event.
for _,Button in pairs (Openers:GetChildren()) do
	Button.Activated:Connect(function()
		
	end)
end
  1. In the function that runs once the button is activated, we loop through the ThingsBeingOpened, and find the correct one based on some sort of identifier. In this case, we have to use string.match to find the number in each button’s name, which is their identifier.
for _,button in pairs (Openers:GetChildren()) do
	button.Activated:Connect(function()
		local number = nil
		for num = 1,4 do
			if string.match(button.Name,num) then
				number = num
			end


		end 
	end)
end
  1. Now that we have the identifier, we loop through ThingsBeingOpened, and see if the Frame we’re currently on is the right on based on the identifier.
for _,button in pairs (Openers:GetChildren()) do
	button.Activated:Connect(function()
		local number = nil
		for num = 1,4 do
			if string.match(button.Name,num) then
				number = num
			end
		end 
		for _, frame in pairs(ThingsBeingOpened:GetChildren()) do
			if string.match(frame.Name, number) then
				--this frame's name has the correct number in it, so we know
				--this is the right one
			end
		end
	end)
end
  1. Now we can do whatever we want to that frame, and it will happen whenever we activate the corresponding button. In this case, we’ll simply make the frame’s visibility be the opposite of what it currently is, for opening and closing functionality.

for _,button in pairs (Openers:GetChildren()) do
	button.Activated:Connect(function()
		local number = nil
		for num = 1,4 do
			if string.match(button.Name,num) then
				number = num
			end
		end 
		for _, frame in pairs(ThingsBeingOpened:GetChildren()) do
			if string.match(frame.Name, number) then
				--this frame's name has the correct number in it, so we know
				--this is the right one
				frame.Visible = not frame.Visible
			end
		end
	end)
end

And Voila


This is really just the surface of what this method can be used to do.

Edit:
But what if you have stuff as children to ThingsBeingOpened or Openers that aren’t supposed to be used? For instance, a Ui list layout. What do you do, since it will error when we loop through them? Simple: filtering.

When we loop through them, we can filter out anything that isn’t supposed to have the functionality we’re giving it.


for _,button in pairs (Openers:GetChildren()) do
    if button:IsA("TextButton") then
	    button.Activated:Connect(function()
		    local number = nil
		    for num = 1,4 do
			    if string.match(button.Name,num) then
				    number = num
			    end
		    end 
		    for _, frame in pairs(ThingsBeingOpened:GetChildren()) do
                 If frame:IsA("Frame") then
			        if string.match(frame.Name, number) then
				        --this frame's name has the correct number in it, so we know
				        --this is the right one
				        frame.Visible = not frame.Visible
			        end
                end
		    end
	    end)
    end
end

No errors cramping our style today :wink:

22 Likes

Finally someone understand how to seriously optimize many things with controlling them through ONE script. Thank you. I’ll bookmark this.

3 Likes

Couldn’t you also do something not with numbers, with names like if you find “shop” in the buttons name and “shop” in the frames name, you’ve found the right object?

That’s correct. There had to be some type of identifier to match them, but it doesn’t matter what it is.

Quick edit made for more clarification in issues you may face.