Is this a good method of connecting buttons to UIs?

I do not consider myself an “advanced” developer, and one of the hardest things for me in Lua is properly organizing UI stuff. Today I decided to sit down and mess around with it and came up with this.

UIHandler:

for _, gui in ipairs(script.Parent.Parent:GetChildren()) do
	if gui:IsA("ScreenGui") then
		local buttons = gui:FindFirstChild("Buttons")
		local modules = script.parent.Modules:FindFirstChild(gui.Name)
		if not buttons or not modules then continue end
		
		for _, frame in ipairs(buttons:GetChildren()) do
			local button = frame:FindFirstChildWhichIsA("TextButton") or frame:FindFirstChildWhichIsA("ImageButton")
			if not button then continue end

			local moduleName = frame.Name
			local module = require(modules:FindFirstChild(moduleName))
			if not module then warn("Module not found for button: " .. moduleName) continue end

			button.MouseButton1Click:Connect(function()
				module.Clicked()
			end)
		end
	end
end 

Module Scripts:

local TemplateButton = {}

function TemplateButton.Clicked()
	print("This is an example of how to set up the UI.")
end

return TemplateButton

What it looks like in the explorer:

Attached is a working demonstration if anybody wants to download it, but hopefully the above is enough to see what it does. It’s intended to just be an easy way to make buttons.

The reason I ask this question is that I think it defeats the purpose of modulescripts to need one for every button (at that point I may as well put a localscript in every button, right?), but I also think just putting localscripts in everything is rather unorganized. I wanted to get outside opinions as I tend to overthink things and want to know what methods other people use to make their UIs functional. If you have any questions, please let me know, and thanks in advance!

UISystem.rbxl (82.9 KB)

2 Likes

No, it’s not.
There is no point of having a module, and there is no point of closure or table.

for _, gui in script.Parent.Parent:GetChildren() do
	if not gui:IsA("ScreenGui") then continue end
	local buttons = gui.Buttons
	for _, frame in buttons:GetChildren() do
		local button = frame.TextButton
		button.MouseButton1Click:Connect(function()
			print(button)
		end)
	end
end
2 Likes

Thanks for responding!

Do you know any places I could look to learn this stuff better? Like what would go into the table and all that?
I’ll look up more stuff about it later (I’m busy at the moment) but if you have any dev forum posts or videos that could be useful it’d be much appreciated.

1 Like

Just look at compiled bytecode

2 Likes

Now that I’ve had more time to sit down and more thoroughly look at this, I just realized that there seems to be a misunderstanding-
The only reason I’m only printing stuff when the button is clicked is to demonstrate. If I were to use this in an actual game, I’d use it so buttons could each have unique functions like opening/closing a menu or exploding a player. As far as I can tell all this is able to do is print the name of the button.
The bytecode thing is still interesting though and I agree that there’s probably a better way than a modulescript for each.

2 Likes

It’s not misunderstanding; it’s me trying to explain why balkanizing stuff with modules is bad.

You can also compile all UI into code to manipulate it directly:

2 Likes

I see. I’ll definitely look more into this, thankyou.

1 Like