How to work on Modular Guis

Modular Guis.

Dear Programmers,

My name is Prof and today I will be teaching you all how to work on modular Guis professionally and how you can start using them for your games.

Explanation

Make a folder called Client and a folder called Modules to store the local scripts and modules.
Make a new module called Main and put it inside the Guis folder which is located in the modules folder.

Below is a screenshot that explains what I meant:

image

In depth explanation of the script:

local Sound = game:GetService("SoundService")
local TweenService = game:GetService("TweenService")

local Main = {}
Main.__index = Main

function Main: ReqInit(GuiName: string, Function: string, Arg1, Arg2, Arg3)
	local foundModule = require(script[GuiName])
	
	return foundModule[Function](Arg1, Arg2, Arg3)
end

ReqInit or RequireInitialise for short is a function used for requiring and executing a function inside of the main module for example:

require(script.Parent["ModuleName"]):Function(Arg1)  

In this case the GuiName is the function modules name that we want to execute.

Function is self explanatory and is the function that you want to execute or well require through this module.

Arg1, Arg2 and Arg3 are the arguments that you will be providing into the function you can add as many arguments as you want depending on the max limit that the inner modules can handle.

function Main: OpenClose(GuiObject)
	if GuiObject:IsA("ScreenGui") then GuiObject.Enabled = not GuiObject.Enabled
	elseif not GuiObject:IsA("ScreenGui") then GuiObject.Visible = not GuiObject.Visible end
end

Not GuiObject.Visible is used to set the visibility of the gui object to the inverse of its current one

function Main: Sound(SoundType: string)
	local Sound = Sound["GuiSounds"][SoundType]
	
	Sound:Play()
end

This is the function used for sounds specifically Gui sounds like clicking and hover.
SountType is just the sound that you want to play.

function Main: Animation(GuiObject: GuiObject, Values: UDim2)
	GuiObject:TweenSize(UDim2.new(Values), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 1)
end

function Main: AnimationReturn(GuiObject: GuiObject, Values: UDim2)
	GuiObject:TweenSize(UDim2.new(Values), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 1)
end

These are the animation functions and are responsible for adding different types of animations like hover open close as well as enter into the scene.

Values in this case being all numbers which are the x and y Udim2 positions for the guis.
They are type checked which is why there are 4 of them indicating the max limit of objects in the area to be 4.

The finished script:

local Sound = game:GetService("SoundService")
local TweenService = game:GetService("TweenService")

local Main = {}
Main.__index = Main

function Main: ReqInit(GuiName: string, Function: string, Arg1, Arg2, Arg3)
	local foundModule = require(script[GuiName])
	
	return foundModule[Function](Arg1, Arg2, Arg3)
end

function Main: OpenClose(GuiObject)
	if GuiObject:IsA("ScreenGui") then GuiObject.Enabled = not GuiObject.Enabled
	elseif not GuiObject:IsA("ScreenGui") then GuiObject.Visible = not GuiObject.Visible end
end

function Main: Sound(SoundType: string)
	local Sound = Sound["GuiSounds"][SoundType]
	
	Sound:Play()
end

function Main: Animation(GuiObject: GuiObject, Values: {number | number | number | number |})
	GuiObject:TweenSize(UDim2.new(Values), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 1)
end

function Main: AnimationReturn(GuiObject: GuiObject, Values: {number | number | number | number |})
	GuiObject:TweenSize(UDim2.new(Values), Enum.EasingDirection.Out, Enum.EasingStyle.Quad, 1)
end

return Main

The local script.

In the Client folder add a local script named GuiHandler

Below is an image of what you need to do:

image

Below I will be talking about the main local script. I usually have 1 of them to control all of the guis so the amount of variables may vary in your script depending on how complex your Gui is.

local Players = game:GetService("Players")
local Player = Players.LocalPlayer

local module = require("The path to your Gui module")

This is just the main part where you will need to require your Gui module and reference the local player and the players service.

local PlayerGui = Player.PlayerGui
local Gui  =  "Your Gui"
local Inner = "If you have an inner frame"

local Frame1 = "A frame"
local Frame2 = "A frame"
local Frame3 = "A frame"

PlayerGui is just the local players playergui.
The Gui as it says is the Gui that you want to program.

The Inner is just if you have an inner frame inside and the 3 frames are the inner frames, though there aren’t supposed to be 3 frames its just as an example.

Button.MouseButton1Click:Connect(function()
	module:OpenClose(Frame)
end)

This is the button click function where we can put the OpenClose function inside to open or close a specific frame.

Full local script:

local Players = game:GetService("Players")
local Player = Players.LocalPlayer

local module = require("The path to your Gui module")

local PlayerGui = Player.PlayerGui
local Gui  =  "Your Gui"
local Inner = "If you have an inner frame"

local Frame1 = "A frame"
local Frame2 = "A frame"
local Frame3 = "A frame"

local Button = "A button if you have one"

Button.MouseButton1Click:Connect(function()
	module:OpenClose(Frame)
end)

A test Gui function module:

Make a new module inside of the Main module with any name that you want preferably the Guis name that you want to program.

Below is a picture of what I mean:

image

local SomeGui = {}
SomeGui.__index = SomeGui

function SomeGui: DoSomething(Object: TextLabel, text: string)
	Object.Text = text
end

return SomeGui

The DoSomething function as you may notice changes the Objects text into the text provided. This is an example of what you can do with the Gui function modules, though this one is very bare bones you can make more complex ones.

Button.MouseButton1Click:Connect(function()
	module:ReqInit("SomeGui", "DoSomething", Label, "testing", nil)
end)

Above is an example of how you can access and execute the function DoSomething with a button and label that you have.

Ending:

In conclusion I hope you find this tutorial useful and that it helped you work with modular Guis which are very important for an organised codebase and game.

This is my first tutorial post or well post in general so I would appreciate if you have any recommendations for me to use in the future.

Hope you Enjoy.
By Prof

16 Likes

Honest question, why do this instead of having a LocalScript for each gui?

1 Like

Modularizing your code keeps everything compact and tidy. You can use a LocalScript for each gui, but depending on what you’re doing, that wouldn’t always be the best option

6 Likes

I agree with omega, the purpose for this tutorial is for organising your codebase and your Guis as I have had cases where there were 100 local scripts in one gui. Modular Guis also save repetition as well as a simpler debug process. Hope this helps.

2 Likes

This guy is a really proffesional scripter by the way, huge thanks to him I have a nice game.

1 Like

I know this is late, but, I ran into this post and I’m not gonna lie this is incredibly useful to me! Very eye opening. One quesiton I do have though is why you decide to list off the args one by one, instead of just using {...} Thanks!