Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Question Faster load times when reloading current scene?

Discussion in 'Scripting' started by dgoyette, Jun 5, 2021.

  1. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,193
    My approach to loading or reloading a scene is to fade to black, load a "Loading..." scene, then immediately kick off a SceneManager.LoadSceneAsync() to load the actual scene I want. The bulk of the time is spent waiting for LoadSceneAsync(), with another substantial chunk of time being consumed when the scene is actually activated.

    A very common behavior in my game is for people to reload the current level they're in, usually because they died. Reloading the current level follows the exactly same flow: Load the "Loading..." scene, then call LoadSceneAsync on the current scene name. The thing that's a bit frustrating is that repeated calls to LoadSceneAsync for the same scene still take quite a long time. Ideally reloading the current scene would be much faster.

    So I was wondering if anyone knew of any techniques for speed up LoadSceneAsync in cases where everything it will be loading is probably already in memory or already on the GPU. I have no idea what LoadSceneAsync is specifically doing, so I don't know how to approach optmizations here, if it's even possible.

    I realize I could try to change my architecture, and not call LoadSceneAsync when reloading a scene. But my scenes contain a large number of dynamically run-time-created and -destroyed objects. Trying to architect a system where every dynamic object is tracked, and returned to its original position on reload, is beyond the scope of my current effort.

    Is there some way to cache some of what LoadSceneAsync is doing, so that subsequence calls to it run faster?
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,514
    Hey there dgoy... here's some random thoughts:

    - does your entire scene need to be reloaded? Or perhaps only parts of it? If only parts, then perhaps break your scenes into the static content (which doesn't reload), and the enemies and player (which does unload / reload). Then you additively load the parts. When you die, unload and reload the player / enemies.

    - for the loading screen (if you even need it anymore!) you can put that in a separate additively-loaded scene, load it and when all the other scenes finish loading, then unload the loading screen. (say that five times fast)

    I almost always break my scenes up into parts. That way I have one "Player Scene" with only the player and enough logic to go away and hide until a spawn point is available, which it will be when the content partial scene loads, and that player scene is what gets reloaded.

    This reload-the-player stuff works particularly well when the scene DOES change and takes damage or partially gets completed, and you want the player to continue midway through after death, but want a brand-new player loaded up.

    Anyway, I've got more scribbles about additive scene loading:

    https://forum.unity.com/threads/right-way-for-performance-divide-scene.1023673/#post-6630961
    https://forum.unity.com/threads/right-way-for-performance-divide-scene.1023673/#post-6754330

    https://forum.unity.com/threads/problem-with-canvas-ui-prefabs.1039075/#post-6726169

    A multi-scene loader thingy:

    https://pastebin.com/Vecczt5Q

    My typical Scene Loader:

    https://gist.github.com/kurtdekker/862da3bc22ee13aff61a7606ece6fdd3

    Other notes on additive scene loading:

    https://forum.unity.com/threads/removing-duplicates-on-load-scene.956568/#post-6233406

    Timing of scene loading:

    https://forum.unity.com/threads/fun...ject-in-the-second-scene.993141/#post-6449718

    Also, if something exists only in one scene, DO NOT MAKE A PREFAB out of it. It's a waste of time and needlessly splits your work between two files, the prefab and the scene, leading to many possible errors and edge cases.

    Checking if everything is ready to go:

    https://forum.unity.com/threads/daily-events-and-content-changes.1108202/#post-7143713
     
  3. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,193
    Thanks for all the details. I'll give those links a look.

    When you say you break it into parts, do you mean that you multiple physical scene files (.unity files) per logical scene? I've definitely seem some examples with Unity's demos, where a single "scene" is actually a dozen or so sub-scenes, all loaded and layered on top of each other, each doing something specific. But it seems like the tooling for editing multiple scenes at once is cumbersome and difficult. Is that what you're doing, though? Multi-scene editing for every level? Or did you mean something else by breaking the scene apart? If you're doing multi-scene editing, what's your workflow? How do you keep all the right scenes open at the same time? I'll check out the pastebin you linked.

    In my case, most of the stuff in a level is static, and wouldn't need to be reloaded, while the dynamic stuff is more limited. I'm not sure if, in your case, you'd have the static stuff in one scene, and the dynamic stuff in another, and only reload the dynamic scene each time? Or, put all the dynamic stuff in a disabled wrapper game object, and make copies of that content on each reload? Or something else entirely?

    Right now, my loading scene is non-additively loaded, so that it wipes out the current scene completely. I see what you mean about changing that to additive loading, if the original scene doesn't need to be fully unloaded.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,514
    Yep!

    Really!? I think it's awesome! You just load ALL the scenes at once (or at least the ones you need) in the editor and work on them!

    The editor can open as many scenes as you want. You just have to make sure you're putting stuff in the right scene.

    By right-clicking on the scene in the hierarchy and setting it active, that will be where new objects are created when you drag.

    I usually have a loader scene that I do NOT load when editing. That scene additively loads all the others. That lets me just press PLAY while I'm editing scenes and everything is already in place and ready to run.
     
  5. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,186
    I've done scene reloads simply by having a reset interface (like, IReset) that includes a ResetItem method. Thus items can have scripts that implement the interface and reset themselves as needed if my player dies.

    For example, if I have a collectable that needs to respawn when the player dies, when they collect the item, I turn it off and add it to a list of IReset. Then if the player dies, I loop through this list calling the ResetItem method, then clear the list.

    In the end, it really just depends on how much you need to reset in the scene. The player has their own respawn method as well, but this is called when they die.
     
  6. dgoyette

    dgoyette

    Joined:
    Jul 1, 2016
    Posts:
    4,193
    I'll give this a look, then. I poked around with the multi-scene concept probably two years ago now, and it seemed that it wasn't very convenient to get all the correct scenes loaded in the editor, and to switch between logical scenes. For example, if I was working on "Level 1", with all of its scenes loaded, then I want to go work on "Level 2", it seemed that I needed to open one of the "Level 2" scenes, then go find and open all the other scenes that are supposed to be in "Level 2". Maybe the tools you use make that more automatic... I jump around from scene to scene a lot in the editor as I make small changes to a large number of scenes, so convenient switching in the editor is pretty important.

    In retrospect, that probably would have been a good idea. I think I chose the "just reload the whole scene" approach out of concern that it would be messy to try to revert everything to their initial state. Some things that sound kind of tricky about that are highly dynamic things, like rocks littered all around the place.

    upload_2021-6-5_19-25-55.png

    In cases like that, I supposed I could restore the initial position when the scene loads, and use that to store those things to those positions later... That all seemed like a difficult, complex thing at one point, and now seems like that would have been doable... but now it seems like a lot of work to change my architecture to that kind of an approach. Definitely a solid idea though.