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

How can I unload (almost) all my scenes?

Discussion in 'Scripting' started by Marscaleb, Apr 10, 2021.

  1. Marscaleb

    Marscaleb

    Joined:
    Jan 7, 2014
    Posts:
    1,036
    I'm trying to have all the scenes in my game load additively. I have one scene that will always stay loaded which will contain the game's manager script, main camera, and such. And every level will just be loaded as an additive scene.

    I'm trying to set up this basic system, and I'm realizing that I'm going to have a problem when I make a call from in the game to return to the title screen. At that point, I need to unload EVERYTHING except for the master scene.
    How do I go about doing this in any kind of effective manner?

    I thought maybe I could write a loop that will tell all scenes to unload. But I how do I effectively track what scenes are loaded? And what if a scene were currently loading async? Like if the player decided to quite just after triggering a load command? Then this system wouldn't detect that scene as being loaded (because it isn't yet) and then it would get loaded.

    I also thought I might just tell the game to load the master scene again, in a basic/non-additive manner. Then Unity would run its normal system of unloading everything. But if I wanted a normal game to do anything at the very beginning (like show a logo for my studio, or play an attract of some kind) then this would be executed again, when I would really want the game to bypass such elements and go straight to the title. Unity recommends that I don't use "Don't Destroy on Load" if I'm using multiple scenes like this; so how would I retain a variable to let the game know to skip all the intro stuff?

    Also, on the subject of unloading scenes, is there any problem with not waiting for a scene to finish unloading? The straight "unloadScene" is marked obsolete, so I'm only supposed to unload scenes async. Off the top of my head, maybe if I immediately start loading a new scene I would be putting a lot into memory for a couple frames. Depending on the platform that might be a problem, although I doubt I'd have enough game content to crash a console doing that.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    38,520
    It's always best to be extremely explicit about what you want to keep around, and when you don't want it anymore.

    As far as a "Master Scene" I don't think there is any value in that. You know the intended lifecycles of your longer-than-one-scene objects, just be explicit about marking them as DontDestroyOnLoad(), and conversely, Destroy() them when you want.

    You can have them all register with a central object that destroys them for you. It's really just an organization thing.

    Remember that marking something as DDOL simply "moves" them to a new virtual scene called DontDestroyOnLoad. Destroying them makes them go away as any other GameObjects.

    EDIT: adding my favorite singleton pattern here:

    Some super-simple Singleton examples to take and modify:

    Simple Unity3D Singleton (no predefined data):

    https://pastebin.com/SuvBWCpJ

    Unity3D Singleton with a Prefab (or a ScriptableObject) used for predefined data:

    https://pastebin.com/cv1vtS6G

    These are pure-code solutions, do not put anything into any scene, just access it via .Instance!

    If it is a GameManager, when the game is over, make a function in that singleton that Destroys itself so the next time you access it you get a fresh one, something like:

    Code (csharp):
    1. public void DestroyThyself()
    2. {
    3.    Destroy(gameObject);
    4.    Instance = null;    // because destroy doesn't happen until end of frame
    5. }