What would be the best way to approach creating an organized GUI system using OOP

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:

local ButtonModule = require(whatever)

Button1.MouseButton1Up:Connect(function()
	ButtonModule.Clicked(Button1)
end)

Button2.MouseButton1Up:Connect(function()
	ButtonModule.Clicked(Button2)
end)

Button3.MouseButton1Up:Connect(function()
	ButtonModule.Clicked(Button3)
end)

I’d also have a separate module script for every single button but again, this would be very messy and unorganized.

I can’t really find any resources out there on how to keep organized when dealing with guis. Any tips or help would be greatly appreciated.

2 Likes

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.

7 Likes

I would do the following:

For open/close buttons:

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.

Happy coding!

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).

2 Likes