0

I would like to populate the UI when I load a scene, with the correct data, instead of placeholders.

When I call "LoadSceneAsync", what would be the first object that is called, so I can fill the UI label with the correct data? I know that there is a scene GameObject, but I am not sure if that would fit my needs.

I am looking for some sort of constructor, called when a new scene object is loaded; to plug in my setup function.

3 Answers 3

2

You say

Indeed I did use "onlevelwasloaded" but the UI element may not be there, ready to go, when I invoke it, which lead to errors

That would be an incredibly sever bug in Unity! :)

Could it be that you are mixing-up Awake and Start somewhere?

One way to think of it is once you call Start, you know all the Awake have already run.

When I call "LoadSceneAsync", what would be the first object that is called, so I can fill the UI label with the correct data

You are still within the same frame.

Once you see LoadSceneAsync you can be absolutely assured everything is Awake 'd.

Or indeed once you use Start you can be absolutely assured everything is Awake 'd.

1) could it be that in some of your UI elements (or whatever) you are doing something in Start which you should do in Awake?

2) if (for some reason) you want to "wait until the next frame", perhaps just during development - then do that, wait a frame. You'll see a flicker, but if that's what you want to do (for some reason) do that.

3) note that if you mean you want to go to the net to get something, well of course you have to wait frames (use Update/coroutine) until the information comes back from the net, obviously. (How else could it be?)


Note that in practice, one should be using UnityEngine.Events.UnityEvent everywhere.

Sign up to request clarification or add additional context in comments.

Comments

1

Maybe this is what you are looking for http://docs.unity3d.com/ScriptReference/MonoBehaviour.OnLevelWasLoaded.html

Comments

0

Relying on Unity internal functioning is not always the way to go. Particularly when dealing with RESTApi (which is somehow what you are dealing with here).

You cannot assume one object will be ready before another except if you control it.

Add a Controller script that uses Awake. In the Awake, call all the methods you are needing and use some callback to generate secondary code when primary is ready.

public class MyController: MonoBehaviour{

    private ServerRequestController serverCtrl = null;
    private UIController uiCtrl = null;
    private void Awake(){
        serverCtrl = this.gameObject.AddComponent<ServerRequestController>();
        uiCtrl =this.gameObject.AddComponent<UIController>();
        serverCtrl.GetData(uiCtrl.SetUI);
    }
}
public class UIController:MonoBehaviour{
    public void SetUI(Data data)
    {
         SetTopImage(data.topImage);
         SetBottomImage(data.bottomImage);

        // And so on
    }
}
public class ServerRequestController:MonoBehaviour{
    public void GetData(Action onCompletion){
        // This may be a coroutine if you fetch from server
        Data data = GetDataFromSomewhere();
        // At this point, your data is ready
        onCompletion(data);
    }
}

Thanks to this, you are now able to know exactly when a piece of code is ready.

6 Comments

Brilliant. Indeed I did use "onlevelwasloaded" but the UI element may not be there, ready to go, when I invoke it, which lead to errors. This take care of syncing, and it is really a nice way to deal with the problem. Thanks!
Could I implement this in my singleton game manager? That object is loaded when the main menu scene is loaded, so it persist when I load the new scene.
Singleton is not related to persistent object. This is actually two separate patterns. If you wish to make it persistent, you would use DontDestroyOnLoad. If you wish to make it a singleton, then you would make it inherit from a singleton class. Both are possible together since they are not related (they kinda complete each other in some ways). Just make sure you are not creating new instances when coming back to the scene that created your manager. Your singleton should take care of that but keep an eye on it though.
There is no such thing as a "singleton" in an ECS scene-based game engine such as Unity. Note that every game object is in fact a singleton. If you think you have a singleton you don't, and you don't understand OO/ECS. (Here's an angry essay on the topic! stackoverflow.com/a/35524924/294884 ) If you have a "game manager", which is fine, that is a "script" on a "game object". That's all there is to it. It's Just That Simple.
@fafase old bean - is there a typo in the code? you'd have to do that in Start not Awake or else everything may not be Awake 'd, right?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.