Let’s say I have 5 different buttons and all of those buttons lead to separate frames to open and close. All 5 of those frames have 5 tabs that can be pressed to open a separate frame inside of the main frame. All 5 of these tabs have different buttons in them that all have completely different functionalities such as buying, selling, trading, developer products etc. What would be the best way to handle creating such a complex hierarchy of guis?
One solution I had to this problem was creating a ModuleScript that has methods inside of it that are common in a lot of different guis, for example: An open and close method for buttons. I’d then apply all the methods to every button I want it applied to but that would seem a bit messy and repepitive to me because this is what I’d imagine it to look like in the main script:
Utilize loops & tables as much as possible. For example, let’s say you have multiple buttons that lead to different tabs like you said. One great way to do this is to utilize the button’s name. If we have buttons:
About
Contact
Shop
Help
Settings
We can use a table and loop to quickly create the different clicked events:
local buttons = GUI:FindFirstChild('ButtonsFolder')
local main = GUI:FindFirstChild('MainFrame')
local buttonData = {
['About'] = GUI:FindFirstChild('AboutFrame'),
['Contact'] = GUI:FindFirstChild('ContactFrame'),
['Shop'] = GUI:FindFirstChild('ShopFrame'),
['Help'] = GUI:FindFirstChild('HelpFrame'),
['Settings'] = GUI:FindFirstChild('SettingsFrame')
}
for _, button in pairs(buttons:GetChildren()) do
button.Activated:Connect(function()
local targetUI = buttonData[button.Name]
main.Visible = false -- Hide main
targetUI.Visible = true -- Show target
end)
end
Obviously I don’t know what your UI hierarchy looks like so I’m just using placeholders but this should give you a general idea of how to handle your UI. It’s also worth having something like a currentFrame UI if you’re switching between frames to keep track of where you are.
Assuming that the buttons are within Frames, and that these frames are within the same gui, you could simply make a loop that passes through each of these frames, find the “close” button and do the action you want to do, here a code example:
local Gui = "Your gui location here"
for _, Frame in pairs(Gui:GetChildren()) do
if Frame:IsA("Frame") and Frame:FindFirstChild("CloseButton") then
Frame:FindFirstChild("CloseButton").MouseButton1Click:Connect(function()
--close the frame
end)
end
end
Same thing for open:
local Gui = "Your gui location here"
for _, Frame in pairs(Gui:GetChildren()) do
if Frame:IsA("Frame") and Frame:FindFirstChild("OpenButton") then
Frame:FindFirstChild("OpenButton").MouseButton1Click:Connect(function()
--open the frame
end)
end
end
For buying / selling / trading, etc i would do this:
assuming that the buttons are inside the frames, I would do the following:
1: locate specific buttons, example:
local Gui = "Your gui location here"
for _, Frame in pairs(Gui:GetChildren()) do
if Frame:IsA("Frame") and Frame:FindFirstChild("TradeButton") then
Frame:FindFirstChild("TradeButton").MouseButton1Click:Connect(function()
--do the stuff
end)
end
end
so on with each one of the buttons that do the same function/action.
I hope i helped you to solve the problem, if so, be sure to mark my reply as a solution.
Generally with UI you can write most interactions into modules. How you organize that is based on what you want to do individually.
The whole point of OOP is to avoid repeating yourself and equip proper inheritance within your environment.
One of my recent projects writes inheritance hierarchies like this:
InterfaceCore module
Constructor class (accepts any type of UI, and assigns custom properties to it as needed).
All necessary UI functions and events loop back to global environment, so that you can call UIObject.new().MouseButton1Click:Wait() … etc.
Animations module
Animation constructor accepting UI.type (custom property & other individual information).
Animation methods and events
Everything eventually indexes InterfaceCore as a metatable, and animation sets are inherited and individually callable.
When writing with OOP in mind, think about the DRY principle as well as general inheritance with any classes you might write. It also helps to write most of your highly used objects a shortcut variable or access location (this could be a table).