Hostingheaderbarlogoj
Join InMotion Hosting for $3.49/mo & get a year on Tuts+ FREE (worth $180). Start today.
Advertisement

Build Arkanoid With Unity: Audio, New Levels, and Deployment

Gift

Want a free year on Tuts+ (worth $180)? Start an InMotion Hosting plan for $3.49/mo.

This post is part of a series called Build Arkanoid With Unity.
Build Arkanoid With Unity: Block Mechanics, Prefabs, and Level Design
Final product image
What You'll Be Creating

In this tutorial series, we'll show you how to recreate the classic Arkanoid (or Breakout) game in Unity, using Unity's native 2D tools. In each post, we'll focus on a specific part of the game; in this post, we'll add sounds and music, create new levels, and deploy the game to different devices and platforms.

Where We Left Off

In the previous tutorials you set up the project, coded the main objects' behaviors, and implemented a score and lives system. If you haven't completed the previous tutorials yet, we strongly recommend you do so before continuing.

Final Preview

Take a look at this demo to see what we're aiming for across the whole series:

Sounds and Music

In the first post in this series, you imported several sound and music files. It is now time to use them. In the Sounds folder, there are three files:

  • hit.wav: to use upon every ball collision.
  • lose.wav: to use when the player loses a life.
  • point.wav: to use then the player scores a point.

We need to modify both the Player and Ball scripts to play these effects. Let's start with the Ball object. 

Initially, we need to add an audio component to the game objects. Select the ball and add an Audio Source (Hierarchy > Inspector > Add Component). Note that you should uncheck the option Play On Awake, if it is checked; otherwise, the sound effects will play automatically when the scene launches.

You have an audio component; now you have to modify the ball script to interact with the component itself. Create a new variable for the sound file. Since you want to access the sound in the editor, the variable should be public:

public AudioClip hitSound;

We're going to make the ball produce a sound every time it collides with something while active. To do this, we use the OnCollisionEnter2D method, check whether the ball is active, and play the clip if so:

void OnCollisionEnter2D(Collision2D collision){
    if (ballIsActive) {
		audio.PlayOneShot (hitSound);
	}
}

Note that you need to check whether the ball is active before playing the sound—otherwise, the sound will constantly start playing when the ball is inactive.

Now, move to the editor and check that you have a new parameter, Hit Sound, in the ball script:

Drag the hit.wav file from the Project tab and drop it on the Hit Sound parameter of the script. You should see something like this:

Press Play, and check that you now hear the correct sound every time the ball bounces off something.

Now let's insert the two remaining sounds in the game. Insert another Audio Source, but this time to the player object. Again, uncheck the Play On Awake option.

Now, open the player script and create two additional variables. The first variable is for the sound played when the player scores some points, and the second is for the sound played when the player loses a life. Both should be declared as public.

public AudioClip pointSound;
public AudioClip lifeSound;

Since you now have the objects, let's modify the addPoints method to play the sound every time it is called. As before, you must call the PlayOneShot method from the audio object:

void addPoints(int points){
    	playerPoints += points;
		audio.PlayOneShot (pointSound);
	}

Now do the same thing in the TakeLife method:

void TakeLife(){
    playerLives--;
	audio.PlayOneShot (lifeSound);
}

Save the script and move to the editor once more. Drag the two remaining sound files to each new player sound (point and life). You should have something like the following image:

Now, Play the game and verify that the three sounds play when expected.

Background Music

Despite the sound effects, the overall sensation while playing the game is quite empty. Let's modify that by adding background music that's different for each level.

In the Hierarchy tab, select the Background object and add an audio source component:

Now, drag Jaunty Gumption.mp3 from the Project tab and drop it on the Audio Clip parameter of the Audio Source component. This time, you should leave the Play On Awake parameter checked, since we want the music to start playing at the beginning of our level. Turn on the Loop option as well; this will make the music play on an infinite loop as long as the level is being played.

Go ahead and press Play! Your game now includes sound and music.

Levels

In order to finish the game, there are two things that we'll address:

  • When the player destroys all blocks, they should move on to the next level.
  • When the player runs out of lives, the game should restart.

Let's start by creating a second level for the game. Instead of creating a level from scratch, we can just duplicate the first level and modify the objects of this new level.

In order to do that, you just need to save your scene as a new one. Click File > Save Scene as..., name it Level2, and place it in the Levels folder. 

To make this level look different from the first one, ideally, we would change the positions of all the blocks. Feel free to do this yourself but, for the purpose of this tutorial, we will only change the background image and the level music.

Select the Background from the Hierarchy and move to the Inspector. Drag the Background2 file from the Sprites\Backgrounds folder to the Sprite component of the Background game object:

To change the background music, you only need to drag the desired music file into the Audio Clip parameter. For Level 2, use the Monkeys Spinning Monkeys.mp3 file.

If you press the Play button you can test this new level. As you can see, it behaves in the same way as the first one, but with a different background and different music. Since the second level is ready, it is now time to handle the two situations identified earlier.

In the player's paddle script, create a new method called WinLose. Here, we'll check for when the player loses all their lives, and react accordingly: if playerLives reaches 0, we simply call the Application.LoadLevel method and re-load the first level.

void WinLose(){
    // restart the game
	if (playerLives == 0) {
	Application.LoadLevel("Level1");		
	}
}

Next, we'll handle the case where all blocks are destroyed, so we want to move to the next level. To determine the number of blocks remaining, we can use the FindGameObjectsWithTag method again, this time searching for objects in the current level tagged Block. If the resulting array has a length of 0, then we know it's time to load the next level.

Since this tutorial only has two levels, then if the player wins the second level, we'll simply close the game (by calling Application.Quit).

The complete snippet for the WinLose method is: 

void WinLose(){
    // restart the game
	if (playerLives == 0) {
		Application.LoadLevel("Level1");		
	}

	// blocks destroyed
	if ((GameObject.FindGameObjectsWithTag ("Block")).Length == 0) {
		// check the current level
		if (Application.loadedLevelName == "Level1") {
			Application.LoadLevel("Level2");
		} else {
			Application.Quit();
		}
	}
}

We'll call the WinLose method in the Update method of the player script—just add it to the end of the method. For simplicity, the complete Update method is:

void Update () {
    	// horizontal movement
		playerPosition.x += Input.GetAxis("Horizontal") * playerVelocity;

		// leave the game
		if (Input.GetKeyDown(KeyCode.Escape)){
			Application.Quit();
		}

		// update the game object transform
		transform.position = playerPosition;

		// boundaries
		if (playerPosition.x < -boundary) {
						transform.position = new Vector3 (-boundary, playerPosition.y, playerPosition.z);		
				} 
		if (playerPosition.x > boundary) {
			transform.position = new Vector3(boundary, playerPosition.y, playerPosition.z);		
		}

		// Check game state
		WinLose ();
	}

Move back to the editor. To make the WinLose method work correctly, you need to tag the blocks in the game. In the Project tab, go to the Prefabs folder and select a block. All blocks are currently untagged, and there is no Block tag, so we must create it. Click the Tag button and select the Add Tag option. Add a new tag called Block:

The game is now ready for testing. Click Play and try it out!

Building and Deploying the Project

Building and deploying the project are usually the final steps in a project's development. In this section, you will learn how to create a final build and the necessary configurations for it to run in a multi-platform environment.

First, you need to add all scenes to a unique build. Click File > Build Settings. A new window will pop up; the Scenes In Build area will probably be blank, like so:

If that is the case, you need to add the scenes we created before. Click Add Current and a scene will be added to the Scenes In Build area:

In our example, we've added the first level. Now, close this window and select the second level in the editor. Click File > Build Settings again, and click Add Current once more:

If you added the second level before the first, don't worry: just use the mouse to swap their positions within the interface (since the first scene in the list is the one that will be loaded when the game is launched).

Once both levels are added in the correct order, click Build and Run and you should see a correct build of your final game.

As you can see, there are several platforms that you can choose to deploy your game for, namely:

  • Web browsers
  • PC, Mac, and Linux
  • Mobile operating systems: iOS, Android, Blackberry, and Windows Phone 8
  • Google Native Client
  • Consoles: Xbox 360, PS3, and Wii
  • Windows Store

The great advantage of using Unity is that you only need to program your game once—then, using the engine, you can quickly and easily deploy it to any of the aforementioned platforms.

However, you should note that some platforms and operating systems have certain limitations in terms of deployment rules. For instance, to deploy to iOS devices you need to have a Mac system and a proper development license. You also need licenses to deploy to PS3 and Xbox.

Challenges

Now that you've completed this tutorial, we think you are prepared to undertake some challenges. You can see these challenges as a mastering knowledge quest.

  1. Add different block styles and configurations: the goal is to define more blocks with different properties, such as different score values and different numbers of hits to kill.
  2. Create an original level: a third level that is completely different from the two of the tutorial. You can use a different background, different music and a different block layout. We would like to see the screenshots in the comment section!
  3. Implement a multiplayer mode using the same keyboard: add the necessary logic to handle input from other keyboard keys, and show the score and lives for the second player in the interface.

Conclusion

This concludes this tutorial series on building Arkanoid using Unity's 2D toolset. We've covered a lot of ground in this short series, and you should now know enough to get started with your own 2D games. If you have any questions or comments, as always, feel free to drop us a line in the comments.

Advertisement