Search Unity

Async scene loading vs just activating/deactivating large chunks of a scene.

Discussion in 'World Building' started by DungeonBrickStudios, Dec 28, 2018.

  1. DungeonBrickStudios

    DungeonBrickStudios

    Joined:
    Jun 9, 2015
    Posts:
    69
    So I'm porting a game to the PC and have realized that my later levels are just too big. Frame drops and such occur even with occlusion culling and other attempts at optimization.

    I tried to go the async scene loading route (i.e. you load parts of the level from separate scenes as needed) but due to just how many interdependent objects exist in the scene, it has proven to be far too much trouble. This as opposed to just activating/deactivating large chunks of the scene, which I got implemented as soon as I compromised towards it. These are not huge open levels by any means, but they are packed with stuff so they're expensive.

    In terms of performance, I got good results doing this but took hits when two large portions became active at the same time. This can be mitigated though if some changes are made to the level design.

    But yeah I was just wondering if this is something that comes up a lot and if it's considered bad practice vs async loading.
     
  2. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    10,157
    This is a scripting question, not a game design one.
     
  3. DungeonBrickStudios

    DungeonBrickStudios

    Joined:
    Jun 9, 2015
    Posts:
    69
    I did double check the FAQ before posting this thread:

    I felt that how one loads a scene could potentially fall somewhere between theory and practice as level design can definitely depend on it. But I can also see this being a more technical topic, since technical issues like "performance" come up. Dunno about scripting though because while scripting is implied (as it would be for game development in general), there are no script specific questions. So yes while I have no idea where this topic would perfectly fit, I did feel it fit here more than it did in scripting.

    Edit: That said I just saw a world building section where I think this topic would probably be more suited for.
     
  4. Kudos. If you report your own thread starter post, you can ask the moderators to move your thread, so it won't be duplicate.

    Yes, you need to design your level the loading portions in mind. Try to visualize when and how the player can arrive to the point you're working on and make sure you divide your space and item-list on a way which can be loaded without considerably hickup. Unfortunately there is no silver bullet here, you will need to play-test a lot and measure milliseconds spent on the load.
    There are assets on the asset store which designed to help you along the way in case you want to care only the design part and not the actual coding part (SectR and WorldStreamer are the two prominent ones)
     
    Last edited by a moderator: Dec 28, 2018
  5. MD_Reptile

    MD_Reptile

    Joined:
    Jan 19, 2012
    Posts:
    2,664
    Writing a good working async scene loader is tricky business. I'd say if your not pretty dangerous with C# and have a good understanding of the scenemanager, then avoid trying to make your own. Another drawback about async scene loading is the editor likes to force the scene to load *not* async, and causes hiccups that wouldn't appear in a build, often making it more difficult to test and profile the system quickly.

    But at the same rate, disabling/enabling of world objects means you still need the entire world (or level or whatever) loaded and then selectively changed much in the same way you would use an async scene loader. That can be a problem on platforms with low memory constraints like mobile, but maybe won't be as big of an issue on desktop games.

    I haven't tried SectR or WorldStreamer but they look like solid tested assets and would be a good headstart on that type of thing, if you can figure out a way to get your objects that have scripting happening and such to cooperate with it, which might mean having a singleton game manager that persists always, and keeps important data that those objects are gonna need when the scene loads (have them grab important vars/prefabs, or assign themselves to some master list or whatever using the manager - if your having problems with things breaking because the scenes aren't loaded from the start).
     
  6. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,618
    This Unite talk could be of interest:

    In this talk, they go over a few things they had to implement to allow loading content without noticeable hiccups. Their "PreAwake" approach is explained at 9:24 min.
     
  7. DungeonBrickStudios

    DungeonBrickStudios

    Joined:
    Jun 9, 2015
    Posts:
    69
    Thanks for the replies guys. I did get noticeable hiccups when I first implemented the Async loading solution, but changing certain things up at the time helped reduce it.

    This is what saves my skin in the current solution I have set up. By loading the entire level first, I can quickly grab all the objects I'd like to track (for my save system and game control to keep tabs on) then have large chunks of the level disabled until needed. But I found with the async loading solution, it was much harder to grab things from other scenes for tracking. It would have required loops that would have to re-insert things upon scene load, and my save system to note which subscene the player was inside, etc. Whereas now the player loads the game in a trigger that automatically enables the world immediately surrounding them. The only extra work I had to do was fragmenting the level properly and covering it with large triggers that decide which gameobjects (level chunks typically) to enable/disable ontriggerenter.

    The enable/disable solution does provide large performance increases, but at the same time feels hackish. Almost like that's not what it was meant specifically for. And I don't know, running it in the editor I feel like the game has a tendency to slow down after a bit, at least in the editor. But restarting Unity makes it smooth as butter again. So I wonder if enabling/disabling so much can cause memory leaks over time. Could be a PC issue at my end too though, I know for a fact one of my ram sticks is slightly defective (does not pass memtest). Or of course a bug in my code.