Unity Cookbook. Scene management
Scene management
Adding new scenes
- Scenes are the different levels or screens of your game
- You can add new scenes to your game with File > New scene
- Then save it to your Scenes folder with File > Save scene
- You can open another scenes from the Project window
- Note: If you open a previously-made Unity project the first time, Unity won’t open any scenes, you have to do them manually from the Project window!
Building a game with multiple scenes
- When you have multiple scenes, you need to add them to your build settings so you’re including them in the game
- File > Build Settings > Scenes in Build
- Either drag-and-drop your scenes here or click Add Open Scenes
- The top-most scene will be the one that gets loaded when the game starts
- See Building for more about Build settings.
Scene manager
- Script Reference: SceneManager
- Scene Manager, uh, manages scenes
- To use it, you need to import
SceneManagement
:using UnityEngine.SceneManagement;
Loading a scene
- To move between scenes, use SceneManager.LoadScene
SceneManager.LoadScene(sceneBuildIndex); SceneManager.LoadScene(sceneName);
- This unloads your current scene and loads the one you specified
- Loading the scene you are currently in resets the scene (but not static variables!)
- To get information about your current scene, use
SceneManager.GetActiveScene()
:if (SceneManager.GetActiveScene().name == "GameOver") { // do stuff }
Loading complex scenes
- To load a scene without unloading your current scene, use LoadSceneMode.Additive
SceneManager.LoadScene("YourScene", LoadSceneMode.Additive);
- Useful for big open worlds and interconnected areas
- If you use it, you might need to unload previously loaded levels as well
- Script Reference: SceneManager.UnloadSceneAsync
Data persistence between scenes
- Learn: Data persistence between scenes
- By default, no values persist when moving from a scene to another
- You can change this by calling DontDestroyOnLoad and giving the gameObject you want to persist as an argument
private void Awake() { DontDestroyOnLoad(gameObject); }
- Note: this only works for root GameObjects - not for children!
Creating a data manager
- We can create a data manager for bookkeeping score etc.
- LevelManager, GameManager, UIManager, etc…
- We create a
static
variable that refers to it (here namedinstance
)- $\Rightarrow$ we can use it easily from anywhere
public class ScoreManager : MonoBehaviour { public static ScoreManager instance; private void Awake() { instance = this; DontDestroyOnLoad(gameObject); } }
ScoreManager.instance.AddScore(1);
- $\Rightarrow$ we can use it easily from anywhere
Prevent other instances of data manager from appearing
-
To make sure you only have one ScoreManager at all times, add these lines to the top of your ScoreManager’s
Awake
method.if (instance != null) { Destroy(gameObject); return; }
-
This is commonly known in software development as the singleton pattern.
Closing the game
- Call
Application.Quit();
when you want to close the game- (Don’t worry, this does not close the Unity editor)
Extra: Do stuff when scene is loaded
Script Reference: SceneManager.sceneLoaded
// called first
void OnEnable()
{
Debug.Log("OnEnable called");
SceneManager.sceneLoaded += OnSceneLoaded;
}
// called second
void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
Debug.Log("OnSceneLoaded: " + scene.name);
Debug.Log(mode);
}
Extra: Listing multiple scenes
- Usable for a Level select screen, etc
- Get a list of files in a given path:
string [] files = System.IO.Directory.GetFiles(path); foreach (string file in files) { //Do work on the files here }
- Then, choose ones that
.EndsWith(".unity")
- Hint:
Application.datapath
tells the root of Assets path
Extra: Resources
- Script Reference: Resources
- Script Reference: Resources.LoadAll
- Loads all assets in a folder or file at path in a Resources folder.