- Home /
Scene loading time issue
We are working on 2D game. We started working in Unity 3.x, when there was no Sprite support (later switched to Unity 4.x). Currently we are using heavily modified NGUI (only to display sprite and font's) on top of which we created our own GUI framework.
We are encountering a problem with prefab instantiation (instantiation is taking too long to complete). When scene starts, we instantiate ~120 prefabs (some are small some not). Total element count after instantiation is: ~5000 GameObjects, ~20, 000 Components.
After we manually delete all Start, Enable and Awake methods instantiation is still taking ~ 6 seconds (that is time user needs to wait between two game screens), which is not acceptable.
Answer by mirdzana · Mar 04, 2014 at 10:38 AM
We've done a lot of tests to see what's slowing down Unity serialization and tried to optimize our hierarchy.
Some of the strange Unity serialization quirks we've found: - private fields with [SerializeField] are costing drastically more than straight public fields. I guess the difference has something to do with Reflection. - serializing references to [System.Serializable] classes is also extremely expensive - [HideInInspector] fields makes a good amounty of serialization overhead even on Mobile devices (?!) - simple private fields do take a toil on load up time, even through they don't serialize. Then when you add [System.NonSerializable] the cost disappears? - Serializing GameObject field pointing to "None" has a huge overhead which disappers when the field is pointing to GameObject on scene (normally it doesn't cost much more than simple int fields)
We discovered these with a series of experiments. GameObject and MonoBehaviour have their own fix serialization overhead, and then cost gets proportional to the number of fields. You can try to confirm all of these behaviours by making prefabs with dummy MonoBehaviours and add various kinds of fields for Unity to serialize.
Also we discovered Application.LoadLevel() has a fixed overhead of ~200ms which is present even when you open an 1GO scene from an 1GO scene in a new project. We optimized scene so it has something like 2500 GameObjects on scene load, and now the cost of loading the scene is ~1,1s on S4, and more on lower-end devices. We still need more progress. We have an idea of serializing bools with bitmasks, as both our and NGUI code have a lot of those.
The idea of using deactivated gameObjects to delay sceneLoad cost sounds interesting.
Nice detective work there... Good luck! Your best solution it sounds might just need to come down to either incremental loading via a coroutine staggered over many frames (in which case things would pop into view as they load), or just quietly pooling objects to be re-activated as needed (with the obvious constant memory overhead that incurs).
Answer by nesis · Mar 04, 2014 at 07:42 AM
You might need to look into streaming in prefabs gradually after level load. If you can persist some of them as deactivated GameObjects that get pre-loaded, you'll also avoid the overhead of runtime instantiation.
If there are any nested GameObjects you can collapse into less nested ones, that might help.