Make smooth scene transitions in Unity/C#

Let’s see how you can cross fade your visuals and your audio when switching between two Unity scenes!

🚀 Find all of my Unity tutorials on Github!

This article is also available on Medium.

This tutorial is available either in video format or in text format – see below 🙂

Why have scene transitions in your game?

Having some transitions between your game scenes is a really nice way to keep your players hooked while changing context. It is a way of preserving immersion and even brings forward the style of your game: simple cuts don’t feel the same as fade ins or zoom effects – your transitions are yet another way to characterise your creation.

Plenty of us remember the visual and sound effects that would trigger whenever you started a fight in the Pokemon games: all throughout the series, these particular moments have always been anchored in our memories because we had this unique transition to associate them with.

Today, we’ll see how to make smooth scene transitions in Unity that cross fade the visuals and the sounds of our game.

The big picture

In Unity, transitions are actually pretty straight-forward to make thanks to the built-in animation system, and some C# coroutines.

In this tutorial, I’ll show you how to have the screen fade to black and then back to transparent when we go out and in our scenes, and I’ll accompany that by a similar cross fade of the background music. All of these will be done via animators and just a dozen lines of C# code.

So – are you ready? Then, let’s dive in! 🙂

Step 1: Preparing the scenes and the scene change mechanism

Before we actually work on our smooth transitions, we first need to create two scenes so we have something to transition between…! For now, we’ll simply have the left-click directly teleport us from the first scene to the second one, or vice-versa.

My scenes are going to be really basic – they’re just gonna have some UI: a coloured background and a label that help us immediately identify which scene we’re in.

In our current (auto-generated) SampleScene, we’ll add a new UI panel element and set its colour to a light pink. Then, we’ll also put a UI text in the middle of screen that displays: “Scene 1”.

We can now rename the scene to Scene 1 and duplicate it. The copy will directly get renamed to Scene 2; we just have to double-click it to go to the new scene, change the background colour (I chose a light blue) and update the text so it says: “Scene 2”.

Before we jump in our code editor, let’s add both scenes to the build settings (Scene 1 will already be listed with index 0; go to Scene 2 and click on “Add Open Scenes” to add it as well):

The project base setup is almost done – we simply have to add some super-basic logic so that when we click the left mouse button, we switch between the two scenes. Let’s create a SceneLoader.cs C# script and put the following code inside it:

This script uses the SceneManagement Unity module to get our current scene, extract its build index, compute the “complementary” one (0 for 1 and 1 for 0), and load the new scene according to this index.

To have our MonoBehavior script execute, we’ll add it to an empty game object in both our scenes, called “MANAGER”. Just go to Scene 1, create an empty object and rename it; then drag the script on it; and finally copy-paste this object in Scene 2.

Now, if you open up Scene 1 again and start the game, you’ll see that when you left-click you’ll go from Scene 1 to Scene 2, and then when you click a second time you’ll go back from Scene 2 to Scene 1, and so on… 🙂

Step 2: Adding the UI cross fade via a black screen

For this feature, we are going to use Unity’s animation system. The idea is to first create a new UI panel that completely covers the screen – let’s name this new object “CrossFade”. Then, we’re going to animate it to have its opacity go from 1 (solid black) to 0 (transparent) during the fade out, and from 0 to 1 during the fade in.

First, we need to create a new Animator Controller asset and drag it onto our “CrossFade” object. Let’s call it “CrossFade” too. Now, if you select this object and open up the Animation window, you’ll be able to create a new clip. I’m first going to take care of the end of the cross fade, i.e. the fade out, and call it “CrossFade-End”.

Make sure that you have the “enable keyframes recording” toggled on, and then record an opacity of 1 on your black colour at frame 0, and an opacity of 0 at frame 60 (= 1 second). You should now be able to play back your animation and check you indeed get a nice little fade out looping again and again:

Now, we actually want to disable this loop – because we don’t wish for our screen to keep fading out indefinitely. To do that, just go to the animation clip and toggle the “Loop Time” property off:

The “CrossFade-Start” animation for the fade in (from transparent to black) is very similar: you simply have to switch the keys so that it starts with an opacity of 0 and ends with an opacity of 1.

If you open your Animator window with the “CrossFade” object still selected, you’ll see that both our animations have been associated to states. Make sure that the “CrossFade-End” is the default state (the one in bright orange) so that, when the scene initially loads, we get a fade out. We’re going to create a transition between the two states that will be conditional on a custom trigger parameter, Start:

This trigger will allow us to tell the animator via C# scripting to go from one state (i.e. one animation) to another. Also, remember to disable any exit time and set the transition duration to 0 so the state changes as soon as we’ve left clicked.

All that’s left to do is to update our SceneLoader class to reference this animator and trigger the animation before changing scene. Because we want to wait for the animation to finish before actually changing scene, we’ll have to convert our LoadNextScene() method to a coroutine by using the IEnumerator return type and adding a yield return new WaitForSeconds(1f):

Note: for more info on coroutines and running functions “on the side” while waiting for something, you can take a look at a previous Unity tutorial I made 😉

Don’t forget to assign the public Animator variable in the Inspector slot on the “MANAGER” object by dragging in the “CrossFade” UI element (in Scene 1 and Scene 2). If you run the game again, you’ll now get some smooth transitions via a black screen when you switch between your scenes, yay!

Step 3: Fading the music, too!

In truth, the music is going to work exactly like the visuals – it will also rely on animations to fade in and out! We’ll animate the volume of an audio source to make the soundtrack louder or lower depending on the transition state.

First things first: let’s add a basic empty object called “AUDIO”, with an “AudioSource” component on it (with “Play On Awake” and “Loop” options turned on):

Note: in this project, I’m using a personal composition that is available here for free, under the CC0 license (no attribution required) 🙂

Now, we want to animate this object so that the “Volume” property of this AudioSource changes over time. But instead of creating a brand new Animator Controller asset for this object, we are going to use an Animator Override Controller called “MusicCrossFade” based on our previous “CrossFade” animator.

Override controllers are extremely useful because they directly inherit all the “structure” from the reference Animator and just let you replace the animations you want to play in each state. So thanks to this override, we’ll have the same states logic and parameters, but we’ll be able to plug in our volume animations instead of the opacity ones.

First, drag the override controller to the “AUDIO” object. Now, create the volume animations just like we did previously: make sure the “AUDIO” object is selected, enable keyframes recording and put one key at frame 0 with volume 0 (resp. 1) for the “MusicCrossFade-End” animation (resp. “MusicCrossFade-Start”), then another key at frame 60 with volume 1 (resp. 0).

Once again, we need to disable the “Loop Time” property on those new animations!

When you’re done, go ahead and drag your animations into the exposed slots:

Finally, let’s create a reference for this Animator in our C# SceneLoader class and call it together with our first animator when we initiate a scene transition:

Tadaa! We now have smooth cross fades on both our visuals and our background music (see the video version for a demo)! 🙂

Conclusion

Scene transitions are easy to do with Unity’s animations and they really bring a lot to a game – both in terms of immersion and story-telling. If you have a bit of time on your hands during your next game project, be sure to give it a try and add some basic transitions: it may put a new spin on your scene switches!

I hope you enjoyed this quick Unity tutorial and the dual video/text versions. Feel free to react in the comments and tell me if you like this new format – and of course, go ahead and share your ideas for future topics you’d like me to make Unity tutorials on! 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *