Is this an efficient method for Gui code?

I’ve been trying to teach my cousin lua code through the development of my game.
This ultimately takes a lot of time and delays the release of the game and occasionally I need to take some of his code and completely re-write it. I use this as an opportunity to show him a different look at how things can be done and he seems to be catching on rather quickly.
In an effort to make sure I’m teaching him proper techniques, I was hoping to just get some advice myself, on whether or not I’m using proper coding techniques and not teaching him something he is going to have to unlearn later and relearn because he learned poor techniques from me.
I’m 100% self taught. Prior to Lua I had absolutely no experience with computers in general and my parents have never been computer proficient either. I know I’ve picked up some bad habits along the way and since I just found this, I’m hoping to use this in the future to get a bit of feedback and advice towards what I should and should not do in my code.

This script controls the main gui for my game. You’ll notice some tweens in the code. Those are purely cosmetic. They provide a hover animation for the main menu buttons.
Our UI is still in development. My cousin and I aren’t particularly UI designers.

The big question I have regarding efficiency is the use of modules for each individual menu button.
I’ve never done this before.
Developmental wise, this makes things extremely efficient for us since we can write up a plugin-type module for each button. It makes the code cleaner, easier to read, and we can organize it faster.
Given all that, what I don’t know: Is it more or less efficient at run time?
Are the gains or losses worth the sacrifice for a more efficient work flow?

MainGuiController.lua (4.6 KB)

Mind putting the code in text instead of sending a lua file? Thanks :stuck_out_tongue:

3 Likes
--[[****** HEADS UP!!! ********\\--
	
	Read NOTES
	
	The hierarchy of the main gui has changed.
	I simplified the structure.
	It might have been my fault, you may have misunderstood my rant about organizing everything in folders.
	Folders are nice when used appropriately.
	In this case however, the Frames of each gui element work nicely for containment and organization.
	The extra folders are redundant and simply make the code structure more complicated.
	
	Please read the comments as you're editing the code. They should help you.
	
	################################################################
	#You should review your script and my script side by side to compare changes.
	#
	#You may use diffchecker dot com online to compare code.
	#^remind me to remove this prior to release. This would be a stupid reason to get banned.^
	################################################################
	
	
	&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
	&
	&	Please update file attributes when editing this script.
	&
	&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
	
--]]

FileAttributes = [[
	
	Author: AZDev
	CoAuthor: CVDev
	Date Created: [12/15/2019]
	Date Last Modified: [12/15/2019]
	Modified by: AZDev
	LuaVersion: RBX 5.1.4
	
	ScriptVersion: 0.0.1
	FileName: MainGuiScript
]]


-- Do not get the players service in a localscript. There is no need for it.

local Player 	= game.Players.LocalPlayer -- The only reference to the PlayersService is here and should be nowhere else.
local Character = Player.Character or Player.CharacterAdded:Wait()

local Camera 	= workspace.CurrentCamera

Camera.CameraType = Enum.CameraType.Scriptable
Camera.CFrame = workspace.UIBox.Cam.CFrame

local Mouse 	= Player:GetMouse()

--[[Note to CVDev:
	Keep your code as organized as possible.
	It helps when you're debugging.
	Variable names should be as descriptive as possible.
	~Variable names do not need to be short. They need to be readable.~
	I'm not saying write an essay with your variable name, but do be descriptive.
		
	Just so it's clear, I'm not trying to rat on your code. You are doing good.
	Like myself, you have some things to learn. That's okay.
	You'll learn them the more you do things.
--]]
	
--// Services \\--

local UserInputService = game:GetService("UserInputService")
	

--// Gui Stuff \\--
-- All your gui related code goes in here. Keep it together. 

--// Main scope Gui variables

local PlayerGui 				= Player:WaitForChild("PlayerGui")

local MainGui 					= PlayerGui:WaitForChild("MainGui")
	local StartScreen 			= MainGui:WaitForChild("StartScreen")
		local Title 			= StartScreen.Title
		local Prompt 			= StartScreen.Prompt

local MainFrame 				= StartScreen:WaitForChild("MainFrame")
	local BackButton 			= MainFrame.Back
		local BackButtonModule 	= require(BackButton.Module)
		BackButton.MouseButton1Click:Connect(function()
			BackButtonModule:Clicked()
		end)
	
	local MainMenu 			= MainFrame:WaitForChild("MainMenu")
		for _, mainButton in pairs(MainMenu:GetChildren()) do
			if mainButton:IsA("TextButton") then
				if mainButton:FindFirstChild("Frame") and mainButton:FindFirstChild("Module") then
					local animGuiFrame = mainButton.Frame
					local mainButtonPlugin = require(mainButton.Module)
					-- Yep, each button gets it's own module now.
					
					
					mainButton.MouseButton1Click:Connect(function()
						mainButtonPlugin:Clicked()
					end)
					
					mainButton.MouseEnter:Connect(function()
						animGuiFrame:TweenSize(
							UDim2.new(0.70, 0, 0.1, 0),
		            		Enum.EasingDirection.Out, 
		            		Enum.EasingStyle.Sine,
		            		0.30,
		            		true
						)
					end)
					
					mainButton.MouseLeave:Connect(function()
						animGuiFrame:TweenSize(
							UDim2.new(0, 0, 0.1, 0),
		            		Enum.EasingDirection.In, 
		            		Enum.EasingStyle.Sine,
		            		0.30,
		            		true
						)
					end)
				end
			end
		end
	
	local LoadoutMenu 		= MainFrame:WaitForChild("LoadoutMenu")
		local LoadoutList 	= LoadoutMenu.List
		local LoadoutTabs 	= LoadoutMenu.tabFrame
-- Already significantly cleaner

-- You'll probably want an explanation of this.
-- Ask me...
local StartScreenInputConnection

function getUserInputWhileAtStartScreen()
	Title.Visible = false
	Prompt.Visible = false
	MainFrame.Visible = true
	MainMenu.Visible = true
	BackButton.Visible = false
	
	print("Opening menu")
	
	StartScreenInputConnection:Disconnect()
end

StartScreenInputConnection = UserInputService.InputBegan:Connect(getUserInputWhileAtStartScreen)
1 Like

Looks pretty efficient and good to me! I also like to use loops in my ui

1 Like

Using WaitForChild is a painful choice when you code GUIs as you cannot reference them when you type and typo may happened, but thats actually ok, not a big problem on efficiency.

Consider using this method this time: Avoiding using WaitForChild a lot in GUI scripts

Thanks for pointing this out. I haven’t really had an issue with it though since I don’t use the built in code editor and don’t have roblox auto completion anyway. The only way I would change this is if it seriously impacted performance. Looking at that thread you shared, efficiency wise, it’s not any better. It’s simply doing the same thing but recursively