1
\$\begingroup\$

I have a GameScene with an initially active GameObject in it, which has a singleton component:

public static ObjectiveManager Instance;

public void Awake()
{
    if (Instance != null && Instance != this)
    {
        Log.Info(this.GetType(), "Instance of this class already exists! CRITICAL");
    }

    ObjectiveManager.Instance = this;
}

Now, when I call:

private void StartGameScene(){
    SceneManager.LoadScene("GameScene");
    ObjectiveManager.Instance.SomeFunction(); // << singleton not initialized
}

I get an error, because ObjectiveManager is not set to an instance of an object.

As LoadScene is a synchronous operation so my guess was that Awake() is called immediately, synchronously. As I can see now, it's not.

Is there any way to determine that all of the objects on the scene have their Awake() already called, without checking each of them with some custom IsReady?

\$\endgroup\$
1
\$\begingroup\$

From Unity’s docs:

When using SceneManager.LoadScene, the loading does not happen immediately, it completes in the next frame. This semi-asynchronous behavior [...] can be confusing because load does not complete immediately.

So there’s no way to do it synchronously. A coroutine running on an object marked as DontDestroyOnLoad would be a simple alternative, although in that case, you may as well use LoadLevelAsync:

private void StartGameScene(){
    DontDestroyOnLoad(this);
    StartCoroutine(StartGameSceneAsync());
}
private IEnumerator StartGameSceneAsync() {
    yield return SceneManager.LoadSceneAsync("GameScene");
    ObjectiveManager.Instance.SomeFunction(); // << singleton should be initialized now.
    Destroy(gameObject); //Since it would normally be destroyed during level load, I assume you didn’t need this around any more.
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.