I’m struggling to understand why unloading this scene doesn’t work.
Debug.Log($"Unloading scene because its prerequisites are not met.");
unloadingOp = SceneManager.UnloadSceneAsync(gameObject.scene, UnloadSceneOptions.UnloadAllEmbeddedSceneObjects);
unloadingOp.completed += (o) => { Debug.Log($"Unload completed"); unloadingOp = null; };
gameObject.SetActive(false);
This immediately results in
NullReferenceException: Object reference not set to an instance of an object
Nightbear.GameFlow.SceneDataControllerBase.Awake () (at Assets/Scripts/GameSpecific/SceneDataController.cs:28)
when I try to set the .completed callback, because unloadingOp is null. (I’ve confirmed that in debug mode) More to the point, the scene is not even unloaded.
I can’t find any indication of why unload might be failing, and there’s no hint in the docs that it’s possible for this method to return a null AsyncOperation.
I’m on Unity 2020 LTS.
Of note, this scene is loaded in the hierarchy when I hit play - it doesn’t appear to have the same issue when trying to unload a scene that was loaded via code. As it happens, the entire point of the bit of code I’m working on right now is to intelligently unload a scene when I’ve hit play while editing the scene but the scene needs other scenes loaded before it can initialize correctly - so for this purpose this is kind of an important situation where unloading really does need to work.
Does anyone have any idea what could be happening here? Anyone had any issues with unloading scenes in this way? Is this just a Unity bug?
Does the scene unload when you don’t subscribe to the completed event on the next line? I vaguely recall some discussion about the async scenemanager calls actually being semi-synchronous in the editor, which wouldn’t really explain this but apparently these calls are a bit weird in how they’re implemented in the editor.
Out of curiosity, why do you set the operation to null in the completed callback?
You say this scene is loaded by the hierarchy, I assume you mean it is scene 0 in the build index. Do you load a different scene before unloading this one? At what point after loading the other scene do you unload this one? Is it in the completed event of loadsceneasync? If so maybe you could wait a frame for the scenen to activate and only then unload the initial one.
No, I added the subscription specifically to try and debug why it wasn’t unloading in the first place.
No, I mean like this:
InitialLoadingScene is scene 0, it loads everything else. BedroomScene is intended to be loaded after other scenes like CoreGameplayScene, but I often have it open to work on level design etc. So the goal of this bit of code is: if I have this scene loaded while editing, then on awake it will be aware that CoreGameplayScene hasn’t loaded, and unload itself, so that the game’s initialization procedure can proceed as designed.
Aha, thinking about this answer made me realize that the reason is because it was in Awake, that is, during the loading process of the same scene I’m asking it to unload. I moved this code to Start() instead, and it worked perfectly.
I will be filing a bug report so they can add this edge case to the documentation and/or throw up a warning, though.