Matt Bird writes all sorts of nonsense, but he dedicates a large chunk of his time to writing game walkthroughs.
It is possible to create an entire game in Unity that takes place within a single scene. Not every game is going to require extensive environments, and there are plenty of clever tricks you can use to fool players into thinking your game is much bigger than it is. That said, it's more common than not that you will need to include scene transitions in your games.
If your player is steering a GameObject that is functionally the same every time, then this is no problem. Simply include a new iteration of it in the new scene. But what if you need to preserve that exact GameObject, stats and all? It's possible, and not that difficult. We'll look at one way to carry a GameObject from one scene to another, and cover how to change scenes in the process.
Step 1: Add the New Scene to the Build Settings
By now you've probably got two scenes ready to go. If not, though, create your second scene now. Click New Scene under File on the top menu and you'll have a new, blank scene in your files.
This is not enough on its own, however. Scenes are not automatically included in a game's build - if they were demos, they would probably be a lot longer than they are - and you need to include them manually. This requires a visit to the Build Settings, which is also under the File dropdown menu, near the bottom.
In the screenshot above we have our two scenes, SampleScene and SceneMove, in the top-left corner of the window. Ensure that there is a checkmark beside both scenes. This will include them in the test build. If you don't have a scene checked off and try to transition to it you'll get an error, so make sure you check off every new scene you create in Build Settings if you know it's going to be included.
(This window is also notable for housing a slew of other, more advanced options for customizing a build of your game. We don't have to deal with any of them now, but it's best you not forget about Build Settings.)
Step 2: Set Up Colliders
There are a number of ways you can trigger a screen transition, but the most common one is the impact of two colliders. Colliders are invisible shapes around GameObjects that register collision with other GameObjects. They can be set to react in a number of different ways.
Add a new component to each of your GameObjects. In this case we are adding them to HubGuy, our moveable GameObject, and SceneTrigger, the white box that will serve as our scene transition point. Make sure to tick off 'Is Trigger' on your scene transition point! This is crucial for making the transition work!
Note that the colliders you use will vary with the objects you're moving around. Since these are two simple 2D GameObjects, we are using Box Collider 2D. Your collider will probably vary based on the kind of game you're making.
Step 3: Code
Now for the hard part. (But not too hard.) There is no built-in trigger for scene transitions in Unity so we will need to make a custom script, attached to our scene transition GameObject, to make it happen. Here we attach a script called SceneSwap to the SceneTrigger GameObject, and plug in the following code.
First off, make sure you include UnityEngine.SceneManagement at the top of the screen with the other namespaces. Without it this won't work. That done, we create a new function, OnTriggerEnter2D. This and other collider functions are built into Unity, and will populate itself as you type. This will vary based on your collider - if you're using a 3D collider you'll want OnTriggerEnter instead. The Collider2D variable registers the colliding GameObject (your player character) as the variable. Name it as you please. (Though do rename it, as the default name, 'collision', can easily lead to mistakes.)
Within OnTriggerEnter2D we want two lines. The first loads out the current scene and loads in the scene with the text name 'SceneMove'. You need to spell this exactly right or you'll get an error. The more-efficient alternative to this is to create a string array that you can populate with scene names and then just call the appropriate number - something along the lines of 'sceneListing' - but we will settle with 'SceneMove' for now.
Normally this would load in the new scene and destroy all of the GameObjects in the old scene. You want to preserve the object that collided with this trigger, however, so we include one more line: DontDestroyOnLoad. Putting colliderObject here will ensure that the exact GameObject is included in the new scene, unchanged in every way.
Test your game out. Assuming all went to plan, when you shift the GameObject into the trigger object you will swap scenes but the player GameObject will still exist. (If you don't have movement code you can manually move the GameObject with your mouse and still see the effect in action.) Done!
Tips to Consider
At the bare bones level, scene transitions and the preservation of GameObjects is pretty simple. However, the very act of hopping scenes brings with it a lot of considerations. Here are a few things to think about as you design your game with scene transitions as a factor.
- When your GameObject is lifted from one scene to the next it will reappear at the exact same coordinates in the next scene. This will probably not be desirable, as it's very rare for exits and entrances in two different scenes to exactly align. Consider setting up a system that checks the GameObject's previous exit point and gives it new entrance coordinates.
- Assuming you have the camera attached to your player's GameObject it will lose control upon entering a new scene. You'll either need to delete the camera in the new scene, or create a system that gives the player's camera control automatically. Note that if the camera is not attached to the GameObject you'll need extra code to prevent it from being destroyed by the scene transition.
- Make sure your scene transitions only trigger when the player collides with the trigger. If you have a game with NPCs wandering around it's inevitable that one of them will walk into the trigger, and if you don't include additional criteria the scene will change. One of the easiest ways to avoid this is to include a 'Player' tag that's only attached to the player's GameObject, and use an if() statement to prevent the transition trigger from going off if anything besides the player enters the trigger zone.
- Transitions between scenes are, aside from a small amount of loading time, instantaneous. This will be quite jarring if you don't include some sort of fading transition. Consider attaching a black square to your UI that you can fade in and out whenever you need to transition between scenes so it's not a sudden, hard cut.