Infinite Roller Tutorial Ten – Audio in Unity

Welcome to Edge of Code’s series of Infinite Roller tutorials. If you’d prefer a video tutorial, you can find one here.

In the previous tutorial, we learned how to create sound effects using Audacity and today we’ll add background music and sound effects to the Infinite Roller game.

First, open your Infinite Roller project and the scene, then click on the Main Camera gameobject in the hierarchy. The inspector will show an Audio Listener component. The Audio Listener is the game’s ears – it’s where it listens to audio from. It is attached to the camera since that is where the player’s view is, and where they expect to hear from.

Sounds can be 2D or 3D. A 2D sound can be heard equally wherever the listener is in the scene. For a 3D sound, the audio emanates from a specific point in the game, and as the audio listener (which is at the camera’s position) moves, the volume of that sound will change.

To add a sound, we need to add an Audio Source component. First, we’ll add the background music we downloaded in the previous tutorial. Create a new gameobject and rename it BackgroundAudio. Add a new component, go to Audio → Audio Source, then drag and drop the background music file (from the Audio folder in the Project window) onto the AudioClip slot. Play On Awake should already be ticked. This means the clip will play when the player starts the game. Also tick Loop to replay the music once it finishes. The background music should be heard everywhere, so it should be 2D – make sure Spatial Blend is set to zero. For background music, Priority should also be set to zero. This tells Unity it is important and shouldn’t be interrupted by other sounds.

Unity tutorial audio adding background music

In the Unity file on the download page, I’ve included my own background music for this rather than using the one downloaded in the previous episode.

Press play to test that the background music plays while the game runs.

Next we’ll add the sound we recorded of the character landing. Select the character gameobject in the hierarchy and add an Audio Source component to it (click on Add Component -> Audio -> Audio Source). This time, drag the landing sound onto the AudioClip slot and deselect Play On Awake as we only want the sound to play when the character lands. This can also be a 2D sound as the camera never gets closer or further from the character.

Open the RollingCharacterController script and create a new private variable

private AudioSource landingSound;

In Awake, use GetComponent to get a reference to the AudioSource:

landingSound = GetComponent<AudioSource>();

Then add a line in OnCollisionEnter2D to play the sound,

if (collision.gameObject.CompareTag("Ground"))
{
	//play the landing sound
	landingSound.Play ();

	numJumps = 0;
}

Save the script, then press play in Unity to test this. You’ll notice that the sound is played not just when the character lands after it jumps, but also whenever it lands on the ground as it bounces along.

One possibility now is to only play the sound when the character lands after we’ve jumped. Another is to set a time limit that the character needs to be off the ground for before the sound plays. Really though, we want a combination of these so that the sound plays when the character lands after a jump, and also when it rolls off a section and lands on the next without jumping or when it bounces quite high.

Go back to the script. To make the sound play when the character lands after jumping, we just need to check that we’ve jumped before playing the sound so that

if (numJumps > 0)
{
	//play the landing sound
	landingSound.Play ();
}

Check this works. You’ll see how weird it is to not hear the sound when the character rolls onto the next section or when it bounces. To fix this, go back to the script and add a new variable

//record the last time it landed
private float lastLandedTime;

And initialise it in Awake():

//initialise
lastLandedTime = Time.time;

Inside OnCollisionEnter2D, as well as playing the sound when the character has jumped, we want to play it when the time between now and lastCurrentTime is more than some limit. So first, create a variable to store the limit,

//min time between landing sounds
private const float LANDED_TIME_LIMIT = 0.8f;

We might need to tweak this value later. Then change OnCollisionEnter2D to

void OnCollisionEnter2D(Collision2D collision)
{
	if (collision.gameObject.CompareTag("Ground"))
	{
		//time now
		float currentTime = Time.time;
		
		//only play the landing sound when have jumped or when long enough time between 
		//this and last time landed has passed	
		if (numJumps > 0 || (currentTime - lastLandedTime > LANDED_TIME_LIMIT))			{
			//play the landing sound				
			landingSound.Play ();
		}
			
		numJumps = 0;
			
		//just landed, so reset time
		lastLandedTime = Time.time;
	}
}

So if the character collides with the ground, we set the current time. Then if the character has jumped, or the difference between the current and last time the character hit the ground is more than the limit, we play the landing sound. The numJumps variable is then set to zero, and lastLandedTime is set to the current time.

Unity tutorial character controller script

Save the script and go back to Unity to test the game. Save the scene and the project.

Today, we’ve learned about audio in Unity and added both background music and sound effects to our game. In the next tutorial, we’ll start looking at how to use larger blocks rather than small squares to generate the terrain.

Remember you can download the files for this tutorial on the Downloads page. See you next time!

PreviousTutorialButtonNextTutorialButton

Comments are closed.