Wait for all GUI script

If anybody is interested, I’ve constructed some code that waits for all GUI to load before proceeding. It basically works by taking the StarterGui’s instances and comparing them to the local player’s PlayerGui and confirming that they match exactly. Use in a LocalScript. Any modifications, criticisms, or ideas are welcome.

local player = game.Players.LocalPlayer;

waitForGui = function(gui)
    if not player:WaitForChild("PlayerGui"):findFirstChild(gui, true) then
        while not player:WaitForChild("PlayerGui"):findFirstChild(gui, true) do wait() end
    end
    for _, v in pairs(player:WaitForChild("PlayerGui"):findFirstChild(gui, true):children()) do
        waitForGui(v.Name);
    end
end
 
for _, v in pairs(game.StarterGui:children()) do
    waitForGui(v.Name);
end
2 Likes

It’s an interesting idea, but at this point you might as well serialise all of your UI elements and construct the UI by script whenever you need it, then you’re sure of what has “loaded” at any point in time. This is what I do in serious projects at least whenever I have a dependency on a particular part of the UI.

1 Like

I have my client starter script clone the UI then execute my gui logic. No need to worry about guis being copied by replication.

Games that use FE do local startergui copying so it shouldn’t be an issue there either.

1 Like

Instead of using FindFirstChild with recursive set to true and having waitForGui() semi-recursive (it is recursive, but doesn’t really add much value), change your waitForGui into waitForGui(wanted,obj):

local function waitForGui(wanted,obj)
	-- wanted is an object somewhere in StarterGui (including descendants)
	-- obj is a "clone" of it as a descendant of some PlayerGui
	checkIfAllChildrenArePresent() -- or wait with WaitForChild
		-- see if all children of 'wanted' are also in 'obj'
	for k,v in pairs(obj:GetChildren()) do
		-- we've checked StarterGui.Gui and PlayerGui.Gui
		-- it's time to check StarterGui.Gui.Frame and PlayerGui.Gui.Frame
		waitForGui(wanted[v.Name],v)
	end
end
-- An implementation of the above could be:
local function waitForGui(wanted,obj)
	for k,v in pairs(wanted:GetChildren()) do
		local found = obj:WaitForChild(v.Name,10)
		assert(found,"Took too long to load, something wrong?")
		waitForGui(v,found)
	end
end

So when you clone an object all its children are guaranteed to be inside?

Locally cloned? Yes. The reason you need to waitforchild on gui is if you’re sending them over the network