I’m trying to make a function that gets a UI inside of playerGui so its easier for all scripts to access UI!
for some reason everything is printing twice and when I try to do: global.GetUI(nameOfUI).Activated:Connect(function()
print(“here”)
end
it prints “here” twice and when I call global.GetUI it prints everything twice aswell
I’ve tried looking on the dev forum but I can’t find anything, I also tried changing the function a little but nothing works
What it prints:
function module.GetUI(name)
if not name then warn("No name provided to GetUi function") return end
local timeStarted = tick()
repeat
for _, v in module.Player:WaitForChild("PlayerGui"):GetDescendants() do
print(v)
if v.Name == name then return v end
task.wait()
end
until tick() - timeStarted >= 10
return warn(name, "UI not found after 10 seconds")
end
module.YieldUI = function(name)
local pgui = module.Player.PlayerGui
while true do
local find = pgui:FindFirstChild(name, true)
if find then
return find
else
pgui.DescendantAdded:Wait()
end
end
end
(edit changed from WaitForChild(“PlayerGui”) to PlayerGui)
I honestly don’t know the issue from just looking, it’s probably something to do with use of return and repeat, and I can’t remember the priority for these off the top of my head.
Either way, there is a much more efficient way to do this.
Currently you are looping a function but also giving a tick limit, which I honestly can’t comprehend what this is supposed to be for.
I’d suggest this VERY COMPLICATED and ADVANCED solution.
@GenericYellowSquid is right on some things. Even in ReplicatedFirst, the PlayerGui already exists and is likely loaded before any client/local script execution.
As for the UI elements, they may or may not be loaded when a script executes. In ReplicatedFirst, it appears they don’t load beforehand.
Even in StarterPlayerScripts, my ScreenGui did not get placed into the PlayerGui until later (due to yielding for Character)
If I disable Players.CharacterAutoLoads in studio, the UI elements in StarterGui are never cloned into PlayerGui.
Refer to @hkep 's post. PlayerGUI is loaded nonetheless. If the descendants arent loaded, they will just return nil from the module.
If they return nil, you could just keep calling the module…
by implementing tick checks, you are doing 10x the work. You could just do something like this:
local guiobj = nil
repeat
guiobj = module:GetUI("Name here"); task.wait()
until guiobj
because being honest, if the gui isn’t loaded upon game start within a couple ten milliseconds, there are probably greater issues at hand like why it should take that long for a PC to load a few hundred pixels
I wouldn’t use that solution, as it yields unnecessarily.
If I wanted to yield for 10 guis that would call task.wait() 10 times in a row in addition to writing extra code outside of a function call.
For reference, task.wait() will yield RunService.Heartbeat at the minimum. This would result in ~ 10 frame = 0.17s yield. The code works but is slow and can be faster.
surely yours was more efficient overall, but i want him to understand that not everything is one giant math problem; unless hes requiring these GUIs within the first 100ms of the server opening then they will exist on the client nonetheless.
but yeah, my solution is definitely not the most efficient.
however, i do believe task.wait() is .017s not .17 because task.wait() is just one frame right?
yes it’s one frame. I said if you ran your code 10 times:
local function yield_ui(name)
local guiobj = nil
repeat
guiobj = module:GetUI("Name here")
task.wait()
until guiobj
return guiobj
end
local frame1 = yield_ui("Frame1")
local frame2 = yield_ui("Frame2")
-- repeat until frame10
As an example if a script needed 10 different UI elements (with unique names).