- Home /
Scene LoadLevelAdditiveAsync and Unloading
I have searched other post without seeing the info I am interested in. What I need to do is load scene A then while the player is progressing through A async additive load B. This part is straight forward, but how should I unload only A while the player is in B, and is there an event once that is accomplished to start the asyn additive load for scene C?
Im concerned with the memory footprint as this would be for a pad (Andtroid/IOS) device. And the scenes are not small, I expect to use this process to load about 10-15 scenes.
Any code snippets are much appreciated! Is there a best way to layout the scenes? How is this process effected by asset bundles? Can they be used to simply this process? ( the scenes have a single shell/room exterior while all the props are the same and I assume should come from a prop asset bundle?)
Thanks for any input/answers/advice
Answer by emscape · Jan 30, 2014 at 07:03 AM
I'm currently occupied by the same problem. I think it would be a nice solution to put all the objects you would want to destroy from the first scene into one empty gameobject, wich you can destroy when you would load in level C
Answer by TonyLi · Jan 30, 2014 at 03:18 PM
I don't mean to preempt @emscape's answer, which is spot on, but I wanted to add some details.
I'll use the word area for a scene that represents an area in the world. This distinguishes it from the current gameplay scene, which will contain any number of loaded areas (loaded via LoadAdditiveXXX) and possibly other gameplay objects. Organize each area under a single root GameObject.
The easiest way to build your areas is to lay them out so they connect correctly in world space. If you were to load all areas at the same time, they would all connect properly.
If each area is positioned at world position (0,0,0), on the other hand, you'll have to manually shift them into place as you load them. (Or always keep the player at (0,0,0) and shift the entire world as the player moves.)
Since each area is contained under a single root GameObject, you can keep track of them by maintaining a list of all of their root GameObjects. To unload a level, just remove it from the list and destroy the root GameObject. If the area uses unique assets, you may want to call Resources.UnloadUnusedAssets afterward to free up memory.
If you're using Unity Free, you can listen for OnWasLevelLoaded to do processing when the area is done loading. Since you're using Pro, you probably want to put the load in a coroutine and just do processing when the AsyncOperation is done.
In practice, rather than just keeping the one or two areas in memory, you may want to break up your scenes into smaller pieces and load a couple areas out. So instead of:
[area1(player)]--[area2]
You have:
[area0]--[area1(player)]--[area2]--[area3]
This way, if the player backtracks, you don't need to reload area0.
If you have access to Jason Gregory's book Game Engine Architecture, he has a good section on loading world pieces. One common way to save memory is to use "airlocks" -- a small area that joins two larger areas. Say you have two large scenes: Central Park and Times Square. You can connect them with a small, twisty alley. When the player moves from Central Park to the alley, you can unload Central Park and load Times Square. Since the alley has twists, the player will never see that Central Park just disappeared.