#Running Scene.GetRootGameObjects Before Scene Activation

1 messages · Page 1 of 1 (latest)

green fractal
#

I have a scene management system that loads scenes additively in a specific manner:

  • Create an AsyncOperation operation and assign operation.allowSceneActivation = false.
  • Load the operation, but because of the allowSceneActivation = false flag the scene is not activated - no lifecycle methods such as Awake or Start are ran on behaviours in the scene.
  • Invoke ScenePrepare event with a reference to the loaded scene.
  • Update the operation assigning operation.allowSceneActivation = true.
  • Load the operation, this time that being activating the scene - running Awake, OnEnable and Start on behaviours in the scene.
  • Invoke SceneActivate event with a reference to the activated scene.

I'm writing a Dependency Injection system that should provide and inject services before scene activation as these service will be used in contexts such as Start. The logic is thus subscribed to the ScenePrepare event, which passes UnityEngine.SceneManagement.Scene scene as a parameter. The scene is defined properly despite it not being activated, however scene.GetRootGameObjects() always returns an empty array. This creates an issue as scene.GetRootGameObjects is essential for the Dependency Injection system. The call does not fail in the context of SceneActivate - there it returns the proper array of root game objects in the scene - so I am fairly certain that it's the order of things that's causing this issue.

I understand this is an incredibly niche issue, but should anoyone ever have stumbled across this or has some idea as to how to solve it, that would be greatly appreciated. It doesn't really make sense to me that the root game objects should not be defined before activating the scene - and hopefully there's a way to get around this.

#

The implementation of the function doesn't really give any information whatsoever.

public void GetRootGameObjects(List<GameObject> rootGameObjects)
{
    if (rootGameObjects.Capacity < rootCount)
        rootGameObjects.Capacity = rootCount;
  
    rootGameObjects.Clear();
  
    if (!IsValid())
        throw new System.ArgumentException("The scene is invalid.");
  
    if (!Application.isPlaying && !isLoaded)
        throw new System.ArgumentException("The scene is not loaded.");
  
    if (rootCount == 0)
        return;
  
    GetRootGameObjectsInternal(handle, rootGameObjects);
}
night sealBOT