Hello everyone in the community!
Today I want to share a small system I created that has been helping me a lot during development. I called it UIReferences.
Basically, it is a script where you simply add a tag to any element in your interface, whether it is a Frame, Button, TextLabel, or any other UI object, and the system will automatically return the reference to that element inside the player’s GUI.
This removes the need to manually traverse the entire UI hierarchy just to find a specific element. Besides making the code cleaner and easier to maintain, it also makes UI access much more practical.
For example:
Without UIReferences:
local playerGui = player:WaitForChild("PlayerGui")
local screenGui = playerGui:WaitForChild("MainUI")
local hudFrame = screenGui:WaitForChild("HUD")
local coinsFrame = hudFrame:WaitForChild("CoinsFrame")
local coinsTextLabel = coinsFrame:WaitForChild("CoinsTextLabel")
coinsTextLabel.Text = "999"
With UIReferences:
In Studio, simply add the COINS_TEXT_LABEL tag to the CoinsTextLabel TextLabel.
local UIReferences = require(Players.LocalPlayer.PlayerScripts.Util.UIReferences)
local coinsTextLabel = UIReferences:GetReference("COINS_TEXT_LABEL")
coinsTextLabel.Text = "999"
Much simpler, cleaner, and easier to maintain. You no longer need to rely on the UI hierarchy structure to access specific elements.
Important:
- Place the script inside
PlayerScripts. - Each tag must be unique. If duplicated tags are found, the system will warn/error about duplicated references.
Code: UIReferences
local UIReferences = {}
local CollectionService = game:GetService("CollectionService")
local Players = game:GetService("Players")
local player = Players.LocalPlayer
function UIReferences:WaitForDescendants(root, ...)
local names = { ... }
local current = root
for _, name in ipairs(names) do
current = current:WaitForChild(name)
while not current do
current = current:WaitForChild(name)
end
end
return current
end
function UIReferences:GetReference(referenceName: string)
local playerGui = player:WaitForChild("PlayerGui")
UIReferences:WaitForDescendants(player, "PlayerGui")
local taggedObjects = CollectionService:GetTagged(referenceName)
if #taggedObjects > 2 then
warn("More than one object found with the tag:", referenceName)
return
end
for _, obj in ipairs(taggedObjects) do
if obj:IsDescendantOf(playerGui) then
return obj
end
end
local thread = coroutine.running()
local connection
connection = CollectionService:GetInstanceAddedSignal(referenceName):Connect(function(obj)
if obj:IsDescendantOf(playerGui) then
connection:Disconnect()
coroutine.resume(thread, obj)
end
end)
return coroutine.yield()
end
return UIReferences