noobtuts

Unity 2D Arkanoid Tutorial

Unity 2D Arkanoid Game

Foreword

Let's make an Arkanoid clone with only 37 lines of code! The original Arkanoid was released a long time ago in 1986, but is still highly addictive and thanks to its arcade style nature it's very easy to develop in Unity.

As usual, everything will be explained as easy as possible so everyone can understand it.

Here is a preview of the final game:
Unity 2D Arkanoid Game

Requirements

Knowledge

This is a beginner Tutorial where no advanced skills are required. Only the Unity basics are somewhat useful to know. If you don't know the Unity basics, feel free to either try and see how far you get or read one of our easier Unity Tutorials like Unity 2D Pong Game first.

Unity Version

Our 2D Arkanoid Tutorial will use Unity 5.3.0f4. Newer versions should work fine as well, older versions may or may not work. The free version of Unity 5 now comes with all the engine features, which makes it the recommended version.

Project Setup

Let's make a game! We will start Unity and select New Project:
Unity New Project

We will name it arkanoid, select any location like C:\, select 2D and click Create Project:
Unity Create new 2D Project

Now we can adjust the Camera to our needs. At first we select the Main Camera GameObject in the Hierarchy, afterwards we adjust the Background Color to something dark and modify the Size like shown in the following image:
Camera in Inspector
Note: the size is pretty much the zoom factor of the camera. We modified it so the overall game will look just about right later on.

The Hexagon Background Pattern

The original Arkanoid game uses a blue hexagon pattern as background. We can create a similar pattern with our drawing tool of choice:
Arkanoid Hexagon Pattern
Note: right click on the image, select Save As..., navigate to the project's Assets folder and save it in a new Sprites folder.

Let's select the Hexagon Pattern Image in the Project Area:
Hexagon Pattern selected

And then modify the Import Settings in the Inspector:
Hexagon Pattern ImportSettings
Note: this tells Unity how to load the image, which compression to use (none in our case) and how big it should be in the final game (exact same size in our case).

Now we can drag the Hexagon Image from the Project Area into the Hierarchy in order to make it part of the game world:
Drag Hexagon Pattern into Hierarchy

So far, so good.

The Sorting Layer

We are making a 2D game and there will be situations where several images are drawn on top of each other, for example when the ball and the hexagon pattern are both drawn.

Let's tell Unity that our hexagon pattern is supposed to be in the background to make sure that the ball is always drawn on top of it (hence visible).

We can use a Sorting Layer for this. We can change the hexagon pattern's Sorting Layer if we take a look at the Sprite Renderer component in the Inspector:
Hexagon SpriteRenderer with default sorting layer

Let's select Add Sorting Layer.. from the Sorting Layer list, then add a Background layer and move it to the first position like shown below:
Background Sorting Layer
Note: Unity draws the layers from top to bottom, hence whatever should be in the background will be at the top of the list.

Now we can select the hexagon pattern again and assign our new Background Sorting Layer to it:
Hexagon Pattern SpriteRenderer with Background Sorting Layer

Adding the Borders

The Border Images

We will add borders to make sure that the ball won't just fly out of the game. We will need one image for each border:

Arkanoid Top Border

Arkanoid Left Border       Arkanoid Right Border
Note: right click each image, select Save As... and save them all in the project's Assets/Sprites folder.

Border ImportSettings

We will use the same Import Settings that we used before:
Border ImportSettings

Now we can drag the borders from the Project Area into the Hierarchy and then position them in the Scene so that they are outside of the hexagon image:
Borders Positioned

Border Physics

At the moment our borders are only images. In order to make the ball collide with them we will have to add a Collider to each border. We can do this by first selecting them in the Hierarchy:
Borders in Hierarchy

Afterwards we can take a look over to the Inspector and select Add Component->Physics 2D->Box Collider 2D:
Borders with Collider

Now the borders are part of the physics world. They still look exactly the same, but instead of being just an image they are now physical walls, too (because of the Collider).

The Racket

The Racket Image

Let's create the racket (called Vaus in the original game). The player will be able to move the racket horizontally to prevent the ball from falling out of the game.

As usual we will begin by drawing a racket image:
Arkanoid Racket
Note: right click on the image, select Save As... and save it in the project's Assets/Sprites folder.

Importing the Racket

We will use the same Import Settings that we used for all other images in our Arkanoid Tutorial:
Racket ImportSettings

Now we can drag the Racket from the Project Area into the Hierarchy and position it on the bottom of our game:
Racket InGame

Racket Physics

Like before, we do want the racket to be part of the physics world because the ball is supposed to collide with it later on. Let's select the racket in the Hierarchy and then press Add Component->Physics 2D->Box Collider 2D in the Inspector:
Racket Collider

There are some more physics to do. The player should be able to move the racket to the left and to the right, and everything in the physics world that is supposed to move around will need a Rigidbody. A Rigidbody takes care of all kinds of things like velocity and gravity, but for now it's enough to remember that everything physical that moves through the game world will need a Rigidbody.

We can add a Rigidbody to the racket by selecting Add Component->Physics 2D->Rigidbody 2D in the Inspector. Afterwards we can modify the Rigidbody 2D to disable Gravity (otherwise the racket would fall out of the game) and make it always have a Fixed Angle (so that it never rotates):
Racket Rigidbody

Racket Movement

The player should be able to move the racket horizontally. This kind of feature can be added with Scripting. Let's select Add Component->New Script in the Inspector, name it Racket and select CSharp for the language:
Create Racket Script

Unity then creates the new Script and automatically adds it to our racket. Let's also take a look at our Project Area and move the Script into a new Scripts folder, just to keep things clean:
Racket Script in Project Area

Let's open the Script by double clicking it. Here is how it looks:

using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {

    // Use this for initialization
    void Start () {
   
    }
   
    // Update is called once per frame
    void Update () {
   
    }
}

Our Start function is automatically called by Unity when starting the game. Our Update function is automatically called over and over again, roughly 60 times per second.

There is yet another type of Update function, it's called FixedUpdate. It's also called over and over again, but in a fixed time interval. Unity's Physics are calculated in the exact same time interval, so it's always a good idea to use FixedUpdate when doing Physics stuff (our racket has a RigidBody and a Collider, which makes it Physics stuff).

We can remove the Start and Update functions and create a FixedUpdate function now:

using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {

    void FixedUpdate () {
   
    }
}

Note: it's important that we name it exactly FixedUpdate because this is the name that Unity expects. We can also make functions with different names, but they wouldn't automatically be called by Unity then.

We will use the Rigidbody's velocity property to make the racket move. The velocity is always the movement direction multiplied by the movement speed. It is of type Vector2, and here are some Vector2 examples:
Vector2 Directions

Let's add a Speed variable to our Script:

using UnityEngine;
using System.Collections;

public class Racket : MonoBehaviour {
    // Movement Speed
    public float speed = 150;
   
    void FixedUpdate () {
   
    }
}

The player should be able to move the racket by pressing either the right/left arrow keys, or the A/D keys, or perhaps even a gamepad's stick. We could either check all of those keys manually, or we could use Unity's GetAxisRaw function to get the Horizontal input. It will return -1 for left, 0 for no direction and 1 for right:

void FixedUpdate () {
    // Get Horizontal Input
    float h = Input.GetAxisRaw("Horizontal");
}

Now we can set the velocity to the movement direction multiplied by the speed:

void FixedUpdate () {
    // Get Horizontal Input
    float h = Input.GetAxisRaw("Horizontal");
   
    // Set Velocity (movement direction * speed)
    GetComponent<Rigidbody2D>().velocity = Vector2.right * h * speed;
}

Note: we access the Rigidbody2D component by using the GetComponent function. Afterwards we set calculate the direction by multiplying Vector2.right with h. If h was -1 then it will result in -Vector2.right (which is left). If h was 0 then it will result in Vector2.zero (which is no direction). If h was 1 then it results in Vector2.right (which is right). Afterwards we multiply it by speed to make it move fast enough.

This is all we had to do to make the racket move. If we press play then we can now move the racket:
Racket Movement

The Ball

The Ball Image

It's time to add the Ball. Like before, we will begin by drawing some kind of ball imagine:

We will use the following Import Settings for the ball image:
Ball ImportSettings

Afterwards we can drag the ball from the Project Area into the Hierarchy in order to add it to our game world. We will position it slightly above the racket:
Arkanoid Ball in Scene

The Ball Collider

The ball should be part of the physics world, so let's select it in the Hierarchy and then press Add Component->Physics 2D->Box Collider 2D to add a Collider:
Ball Collider

The ball should also bounce off walls. If it flies directly towards a wall then it should bounce off into the opposite direction. If it hits the wall in a 45° angle then it should bounce off in a -45° angle (and so on). The math behind this is rather easy and could be done with a Script, but we will do it the easiest way possible by assigning a Physics Material to the Ball Collider. Physics Materials contain information about the physical aspects of Colliders like Friction and Bounciness.

Let's right click in the Project Area, choose Create->Physics2D Material and name it BallMaterial:
Ball Material in Project Area

Afterwards we can take a look in the Inspector and adjust the material properties in order to make it bounce off:
Ball Material in Inspector

Now we just have to drag the material from the Project Area into the Material slot of the Ball's Collider:
Ball Collider with Physics Material

Now the ball will bounce off when it hits a wall.

The Ball Rigidbody

The ball is already part of the physics world, but everything moving should always have a Rigidbody attached to it. We can add one to our ball by selecting Add Component->Physics 2D->Rigidbody 2D in the Inspector.

A few Rigidbody modifications are required:

Ball Rigidbody
Note: the modifications may look like advanced physics stuff, but no worries. The common way to find out these settings is by testing the game and then modifying the Rigidbody step by step to get the effects that we want.

If we would press Play now then the ball wouldn't move at all, because it has no default velocity. Let's select Add Component->New Script in the Inspector, name it Ball and select CSharp for the language. We will also move it into our Scripts folder in the Project Area and then open it:

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

    // Use this for initialization
    void Start () {
   
    }
   
    // Update is called once per frame
    void Update () {
   
    }
}

We won't need the Update function, so let's remove it:

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {

    // Use this for initialization
    void Start () {
   
    }
}

Let's use the Rigidbody's velocity property to make it move upwards by a certain speed:

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {
    // Movement Speed
    public float speed = 100.0f;
   
    // Use this for initialization
    void Start () {
        GetComponent<Rigidbody2D>().velocity = Vector2.up * speed;
    }
}

We can press play to see the Ball bounce off the borders:
Ball Bouncing off

The Ball <-> Racket Collision Angle

We are getting closer to the finish line already. We will now add a cool game play feature to the ball vs. racket collision. We want the player to be able to have some control about the ball's outgoing angle when it hits the racket:
unity-2d-pong-game-racket-bounce-angles

Let's open the ball script so we can implement the outgoing angle feature. We will use Unity's OnCollisionEnter2D function that is automatically called by Unity whenever the ball collides with something else:

using UnityEngine;
using System.Collections;

public class Ball : MonoBehaviour {
    // Movement Speed
    public float speed = 100.0f;
   
    // Use this for initialization
    void Start () {
        GetComponent<Rigidbody2D>().velocity = Vector2.up * speed;
    }
   
    void OnCollisionEnter2D(Collision2D col) {
        // This function is called whenever the ball
        // collides with something
    }
}

We will need some kind of code that calculates the ball's velocity depending on where it hit the racket.

The value of y will always be 1, because we want it to fly towards the top and not towards the bottom. The value of x requires some thought. It will be somewhere between -1 and 1, pretty much like this:

1  -0.5  0  0.5   1  <- x value depending on where it was hit
===================  <- this is the racket

All we really have to do is find out where the ball is, in relation to the racket. We can do so by simply dividing the ball's x coordinate by the racket's width. Here is our function for it:

float hitFactor(Vector2 ballPos, Vector2 racketPos,
                float racketWidth) {
    // ascii art:
    //
    // 1  -0.5  0  0.5   1  <- x value
    // ===================  <- racket
    //
    return (ballPos.x - racketPos.x) / racketWidth;
}

Note: we subtract the racketPos.x value from the ballPos.x value in order to get the relative position.

Here is our final OnCollisionEnter2D function:

void OnCollisionEnter2D(Collision2D col) {
    // Hit the Racket?
    if (col.gameObject.name == "racket") {
        // Calculate hit Factor
        float x=hitFactor(transform.position,
                          col.transform.position,
                          col.collider.bounds.size.x);

        // Calculate direction, set length to 1
        Vector2 dir = new Vector2(x, 1).normalized;

        // Set Velocity with dir * speed
        GetComponent<Rigidbody2D>().velocity = dir * speed;
    }
}

Note: please read through the comments in order to understand what's going on.

If we press play, then we can now influence the ball's bouncing direction depending on where it hit the racket.

Adding Blocks

It's time for some blocks. After all, Arkanoid is boring without something to destroy.

We will use the following images for our blocks:

Note: right click each image, select Save As... and save them all in the project's Assets/Sprites folder.

Let's select the red block image in our Project Area and then use these Import Settings in the Inspector:
Block Import Settings

Like before, we can now drag it from the Project Area into the Hierarchy and then position it at the top left of our game:
Block in Scene

In order for the block to be part of the physics world, we will select Add Component->Physics 2D->Box Collider 2D in the Inspector:
Block Collider

We want the block to be destroyed after it was hit by the ball. This kind of behavior is always implemented with a Script. Let's select Add Component->New Script in the Inspector, name it Block and select CSharp for the language. We will move it into our Scripts folder again and then open it:

using UnityEngine;
using System.Collections;

public class Block : MonoBehaviour {

    // Use this for initialization
    void Start () {
   
    }
   
    // Update is called once per frame
    void Update () {
   
    }
}

We can remove the Start and the Update functions, because we won't need them. We are already familiar with the OnCollisionEnter2D function, so let's use it again:

using UnityEngine;
using System.Collections;

public class Block : MonoBehaviour {

    void OnCollisionEnter2D(Collision2D collisionInfo) {
        // Destroy the whole Block
        Destroy(gameObject);
    }
}

Note: Destroy(this) would only destroy the Block Script component. If we want to destroy the whole Block, then we always have to use Destroy(gameObject), which destroys the Block's GameObject itself.

Afterwards we can duplicate the block a few times (select it in the Hierarchy and then press Ctrl + D or right click -> Duplicate) and then position the copies somewhere else in the Scene:
Block duplicated

We will repeat this process for each of the different block color images in our Project:
All Blocks
Note: we can reuse our Block Script for the other Blocks, too.

And that's it! If we press play then we can enjoy the awesome result of our Unity 2D Arkanoid Tutorial:
Unity 2D Arkanoid Game

Summary

We just learned how to make a nice little Arkanoid Clone in Unity. We created a project that is fast, clean and state of the art. As usual, now it's up to you to make the game more fun. Here are some improvement ideas:

Arcade games are just about the best way to learn how to develop a game and how to make it fun. Take your time, play around with it and make it awesome!


Download Source Code & Project Files

The Unity 2D Arkanoid Tutorial source code & project files can be downloaded by Premium members.

All Tutorials. All Source Codes & Project Files. One time Payment.
Get Premium today!