Understanding scenes in Unity3d
I have some confusion with scenes in Unity3d and I was not able to find any resources about them.
- When should scenes be used? For example in a platformer would every level have to be a different scene? Would the main menu be a scene?
- Can one overlay scenes?
- How do assets work between scenes? Are they attached to each individual scene and have to be reloaded every time. Can one specify when an asset is no longer needed?
- How does one send data between scenes/interface between scenes? I understand that this is a broad topic, but I didn't want to spam with multiple questions.
Solution 1:
When should scenes be used? For example in a platformer would every level have to be a different scene? Would the main menu be a scene?
There are no general rules about that. In theory you may have just one scene for the whole game. How you organize your scenes is entirely up to you and often depends on the type of game you are creating.
I think that there are at least 3 features to be considered of using scenes:
- they are a logical container for all pre-instantiated objects that might be useful to divide your game into multiple levels/sections.
- You can serialize cross references between
GameObjects
andComponents
inside a scene (if GO A needs a ref to GO B, and they belong to the same scene, the reference can be serialized and you no longer need to find the referenced object at runtime) - When you load (not in an additive way) another scene, the resources already loaded into memory are automatically released
Can one overlay scenes?
Yes you can using LoadAdditive. Unfortunately, once 2 scenes are both loaded into memory there is no automatic way of distinguish objects belonging to one or the other. So if you load additive a second level environment, it's up to you to keep track of the previous environment and explicitly destroy it if you need to.
How do assets work between scenes? Are they attached to each individual scene and have to be reloaded every time. Can one specify when an asset is no longer needed?
As defaults every GameObject
of a scene will be destroyed once the new scene is loaded (unless you use an additive scene loading). A way to make a GameObject
survive across scenes is to mark it using DontDestroyOnLoad.
If you need to share a particular "configuration" of a GameObject, you can store it as a prefab, and reference it across scenes (but remember that once in a scene it's a prefab instance, so the GO shares with the prefab the initial serialized and not overriden properties, but 2 instances of the same prefab are different objects).
How does one send data between scenes/interface between scenes?
Several ways, depending on what kind of persistent data you want to share.
- For a particular
GameObject
instance let the object survive usingDontDestroyOnLoad
. - If you have some configuration data that doesn't need to be attached to a specific
GameObject
you can consider storing a ScriptableObject inside the AssetDatabase and reference it. - If you have data that must persist across different game sessions you can consider storing them into PlayerPrefs.
There are 2 other ways that I don't like, but just to cite them:
- Using a static field can sometimes help you in doing that, but it has several problems from my point of view
- Save and load from disk (could be useful in several situations, but often it's a platform dependent way and you can have some trouble especially on different mobile platforms)
This is a broad topic btw, I hope this answer can be a quite decent overview.
Solution 2:
When should scenes be used? For example in a platformer would every level have to be a different scene? Would the main menu be a scene?
There is no rule as to how many scenes you need to have in your game. However, scenes allow you to logically separate out parts of your game from the rest of it. You have to have a minimum of one scene.
By main menu, if you are referring to a canvas with your UI elements, it will be IN a scene and not a scene itself. Canvas is just another GameObject, that we mostly happen to use for showing game menus. I mostly create a Canvas GameObject, put a script by the name of "UIManager" and put DontDestroyOnLoad on it, so I have access to it in all scenes. Make it Singleton and I ensure that it is not duplicated.
Can one overlay scenes?
Yes, there is no restriction as to how many scenes you can load at a time. What purpose do you plan to overlay scenes though? Maybe there is a better way than loading additively.
How do assets work between scenes? Are they attached to each individual scene and have to be reloaded every time. Can one specify when an asset is no longer needed?
Assets are what you see in your 'project' hierarchy. I think you meant "GameObject"s in the scene, and if so, think of your gameobjects as entities with components (Entity-Component System). All entities in a scene get destroyed when its parent scene is destroyed until explicitly stated not to, using DontDestroyOnLoad in some component (a monobehavior in case of unity). The destroyed ones will get garbage collected.
So how they are loaded (or reloaded) depends on your implementation, on whether you are instantiating/destroying them time an again or if you put their instantiated prefabs in a cached object and retrieving later from it.
How does one send data between scenes/interface between scenes?
Heisen covered the ones I could think of. Just to add a little bit to it, it also depends on how you want to the architect your project. So if you had an underlying data structure to e.g. hold Commands, you are free to use it in any part of your project