Uninomicon

Documenting the dark corners of the Unity Engine.

User Tools

Site Tools


scenemanager

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
scenemanager [2021/02/08 00:58]
uninomiconadmin
scenemanager [2022/01/30 19:55] (current)
narry Added details about an undocumented quirk with occlusion culling in additive scenes
Line 1: Line 1:
-SceneManager+====== SceneManager ======
  
-Notes: 
  
-`SceneManager.sceneLoaded` is called *after* the loaded Scene Awakes. +==== When does scene loading happen? ==== 
-Scene Loading always happens at the start of the Update loop, within the `EarlyUpdatephase of the PlayerLoop.+Scene loading and unloading happens at the start of the Update loop, within the ''EarlyUpdate.UpdatePreloading'' phase of the [[PlayerLoop]], and once during the Initialization phase of the player, before the first Update loop.
  
-The Unity scene flushing pipeline works differently in the initialization phase of the player. +Player Loop Phases: 
-Scene loads thats are queued during initialization are blocked and fully loaded before the game starts. +  * __Initialization__ (Scene Loading happens here)  
-For example, if SceneManager.LoadSceneAsync is called in the Awake of the very first scene (ie. called before the first Update), then the engine will wait to fully load that scene as well, before starting the first Update.+  * Game Loop 
 +    * Early Update 
 +      * __UpdatePreloading__ (Scene Loading happens here) 
 +    * FixedUpdate 
 +    * Update
  
-It is untested if this is also the case for SceneManager.UnloadSceneAsync. However, because Unity documentation mentions that that the scene  
-loading queue is a pipeline, and only one AsyncOperation can progress at a time, I would suspect that the Engine simply "flushes" the scene loading queue 
-during initialization. 
  
-Phases: +===== The Scene Loading Queue =====
-- Initialization (Scene Loading happens here) +
-- Game Loop +
- - Early Update +
-   - `UpdatePreloading` (Scene Loading happens here) +
- - Update+
  
-(The scene load pipeline is fully flushed) I don't yet know how it handles unloads if they are in +The scene loading queue is pipeline, and only one AsyncOperation can progress at a timeCalling ''SceneManager.LoadSceneAsync'' or ''SceneManager.UnloadSceneAsync'' adds new AsyncOperation onto the end of the queue.
-the pipeline thenso if we need this behaviour we should debug and see how it works. +
-If scene unloads get flushed too, we'll need to add bit of logic for it, in the same way LoadSceneAsync +
-does.+
  
-The scene loading pipeline only seems to load one sceneevery other frame. That is to say if you have 3 small scenes in the pipeline (Scene1, Scene2, Scene3), loading additively, the engine will load them at the following times: +During the ''UpdatePreloading'' phaseUnity will execute the next operation in the scene loading queue. 
- - Frame N+0: Scene1 +
- - Frame N+1: ---- +
- - Frame N+2: Scene 2 +
- - Frame N+3: ---- +
- - Frame N+4: Scene 3 +
-  +
-## Build Pipeline+
  
-Scenes are built during standalone in the following way: ' +The scene loading pipeline only seems to execute a single operation, every other frame.<sup>[//[[:wiki:tag:research-needed|research needed]]//]</sup> If you have small scenes in the pipeline (Scene1, Scene2, Scene3), loading additively, the engine will load them at the following times:
- 0. The active scenes are closed. +
- 1. Each Scene in the BuildSettings is opened. At this point prefabs are still prefab instances. +
- 2. EditorSceneManager.sceneOpened callback is called. +
- 3. Prefabs in the scene are flattened (turned into normal game objects)+
- 4. [IProcessScene] and PostProcessScene callbacks are called. +
- 5. The final scene file is saved into the standalone build file. +
- 6. Repeat for next scene +
-.+
  
 +  * Frame N+0: Scene1  
 +  * Frame N+1: ---
 +  * Frame N+2: Scene 2  
 +  * Frame N+3: --- 
 +  * Frame N+4: Scene 3
  
 +
 +==== Initialization ====
 +
 +The Engine fully "flushes" the scene loading queue during initialization. This works differently than the way Unity loads scenes during the EarlyUpdate.
 +
 +**All** AsyncOperations that are queued during initialization are fully loaded during initialization. For example, if ''SceneManager.LoadSceneAsync'' is called in the Awake of the very first scene((ie. called before the first Update)), the engine will load this new scene before finishing Initialization.
 +
 +Scene unloads are probably flushed if they are in the pipeline, too.<sup>[//[[:wiki:tag:research-needed|research needed]]//]</sup>
 +
 +===== Build Pipeline =====
 +
 +Scenes are built during standalone build in the following way:
 +
 +  - The active scenes are closed.  
 +  - Each Scene in the BuildSettings is opened. At this point prefabs are still prefab instances.  
 +  - ''EditorSceneManager.sceneOpened'' callback is called.  
 +  - Prefabs in the scene are flattened (turned into normal game objects).  
 +  - [[IProcessScene]] and PostProcessScene callbacks are called.  
 +  - The final scene file is saved into the standalone build file.  
 +  - Repeat for next scene.
 +
 +===== Sample Scene Load (Editor) =====
 +
 +Here is an example of a scene loading additively **in the middle** of a game, **in the editor**. Note that:
 +
 +  * Prefabs.MergePrefabs (turning prefabs into gameobjects) happens before any other callback. (editor only)
 +  * Lightmapping is applied / loaded after Awake/OnEnable.
 +  * SceneManager.sceneLoaded happens after PostProcessScene.
 +
 +{{ :engine:unity_moxtvtiv0k.png?400 }}
 +
 +===== Scattered Notes =====
 +  * During a scene load (ie. Awake) the loading scene has ''scene.isLoaded=false''
 +  * During a scene unload (ie. Destroy) the unloading scene has ''scene.isLoaded=false''. ((You might expect during the unload phase that isLoaded=true, but this is not the case, even though all of the Scene objects are still perfectly loaded and accessible))
 +  * ''ISerializationCallbackReceiver.OnAfterDeserialize'' is called before the async loading of heavy scene resources (e.g. textures) so can be used for running scene-specific thread-aware code early in the loading process.((Unlike ''MonoBehaviour'' events which are called at the end.))
 +  * When using ''LoadSceneMode.Additive'', using the ''SceneManager.sceneLoaded'' callback and setting ''SceneManager.SetActiveScene(scene)'' within this callback results in Unity replacing the currently loaded occlusion culling data with the occlusion culling data from this newly loaded scene. [[https://docs.unity3d.com/Manual/occlusion-culling-scene-loading.html|This goes directly against what is documented, which states Unity will only use the culling data from the first loaded scene]]. This undocumented behavior has been tested in 2018.4-2020.3, and may or may not work in other versions of Unity.
 +
 +
 +----
 +
 +===== API Notes: =====
 +=== SceneManager.sceneLoaded ===
 +  * Called **after** the loaded Scene Awakes.
 +
 +
 + 
scenemanager.1612745936.txt.gz · Last modified: 2021/02/08 00:58 by uninomiconadmin