Is there a way to wait for a GUI to fully load?

Hey, so what I mean by this is like, is there any way to wait the absolute needed time for a GUI to load in all the elements?

So for example, if I were to index something within it, like so:

GUI.FrameThing

If I don’t put a wait at the top of my code here, there’s a chance it’ll say that this element is nil, because it hasn’t loaded in yet. So right now I just put a five second wait at the top of my code to let the GUI fully load in, and also that code doesn’t have to run yet because the loading screen is already taking place. But I just wondered if there’s a way, to determine if a GUI has fully loaded in, aka, all the elements exist, without having to do a bunch of recursing functions and all that…

Thanks!

5 Likes

Use the following:

GUI:WaitForChild("FrameThing")

This code will make the script wait until FrameThing loaded and then return it.

5 Likes

Roblox has provided the method WaitForChild to wait for a child to load, and will return the child once it is added. In this situation, just do

local frame = gui:WaitForChild("Frame")
6 Likes

Hey thanks guys. I’m actually aware of that method however, I was more curious as if there was a way to determine if the entire GUI had loaded, aka, everything in it.

Might get a little tough to put WaitForChild’s and variables for every single element I’m expecting to load in it. xd

1 Like

You only need to use WaitForChild() the first time you wait for the element. You don’t need to use it for the same element later on.

if gui:WaitForChild("Frame").Visible then
    gui.Frame.Visible = false
end

If you use a lot of different elements, then well, you do have to wait for each of them.

2 Likes

Using Instance:WaitForChild will avoid the need for an arbitrary yield at the top of your script. However…

Using the function is only necessary when:

  • Accessing instances created during runtime.
  • Accessing instances outside of ReplicatedFirst from a LocalScript inside ReplicatedFirst without loaded protection.
  • Accessing instances from a LocalScript with streaming enabled.

Other than that, instances will always have loaded. You can learn more here.

cc @Amiaa16

4 Likes

As multiple others have mentioned, :WaitForChild() will wait for the instance (child) to appear.
If you want to be waiting for other assets to load then your best bet is to use the property .IsLoaded which will check if the asset has loaded.
You can also make use of :PreloadAsync()
Where you can put the asset ids of your images inside of it. You can make an array of ids which relates to all of your image ids. You can loop through all of the descendants of the Gui to find all of the ImageButtons and ImageLabels and wait for them to load.

As there’s no real way to see if ordinary frames and buttons show up other than :WaitForChild() but it’s not exactly the correct way to do that.
Here’s an example:

local ContentProvider = game:GetService("ContentProvider")
local AssetIds = {24453,43252,24144} -- Your image ids

print("This gui is currently loading")

local GuiDescendants = Gui:GetDescendants()

for i,v in pairs(GuiDescendants)do
	if v:IsA("ImageLabel") or v:IsA("ImageButton") then
	     repeat wait() until v.IsLoaded
	end
end
ContentProvider:PreloadAsync(AssetIds)
print("Gui is loaded")

This isn’t a rigid solution but its one way to get around

6 Likes

It’s not something you necessarily need to explicitly code line by line. If the content of the GUI container is known at publish time, you can write a server script to GetDescendants on it and write the whole structure into a Lua table that you can send to the client as a manifest, or you can even pre-generate it before you publish and have it in a LocalScript. Then you just wait for it all in a coroutine. A single WaitForChild in a loop is all you need. I do the former, since I don’t like to have extra build steps I have to remember to do before publishing.

EDIT: Basically, what I do is similar to what uJordy shows above, just with an extra step to automate the building of the asset list, and I put it in a coroutine that takes a callback function to call when the loading is done.

1 Like

There isn’t really a way to determine when a Gui fully loads, not sure where all this talk about WaitForChild is coming from. On the other hand, cloning is a synchronous operation so the Gui’s descendants should be available when its ancestor is (the LayerCollector).

3 Likes

He isn’t talking about cloning an object, he is talking about how to make sure that something is loaded. Which the most effective way being to use WaitForChild.

1 Like

You misunderstand the point of my post.

There is no way to check if an Instance has loaded or not, because it’s already “loaded”. You can check if an associated asset has been loaded, but you can’t check if all the descendants have been replicated. Cloning is a synchronous operation, which is what is needed to get the Gui to the player (whether it’s in StarterGui or added at runtime later). All Guis are cloned.

WaitForChild on the ancestor object is the closest you can get to ensuring that something has “loaded” (it’s actually replicated - loaded only applies to assets). It’s descendants would be implicitly available because, again, cloning is synchronous.

3 Likes