02-Unity 2D Arkanoid Tutorial
02-Unity 2D Arkanoid Tutorial
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.
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 2018.3.14f1. Newer versions should work fine as well,
however please note that older versions of Unity may not work as described in this tutorial. For best
results, keep to the 2018.3 versions.
If you have not already installed Unity 2018.3 via the Unity Hub, please follow the About the Unity
Engine portion of the 2D Pong Game guide and return after installing Unity Hub and Unity 2018.3.
Project Initialization
Note: The screenshots shown in the Unity Hub are from 2.x version. Older versions will look different, but it
is mostly the same. Some elements in older versions are drop-down menus instead of the new visual layout.
Let's make a game! We will start the Unity Hub and select New Project:
We will name it arkanoid, select any location like C:\GameDev, select 2D and click Create Project:
Note: It is always recommended to make sure you have write access to your project's folder. Due to system
protection (and/or restrictions) Windows will sometimes cause refuse to create folders in your hard disk root
folder causing Unity to throw Access Denied errors. If you get such an error, try a different folder - for
example, C:\Users\YourUserName\GameDev usually works, or a folder on a dedicated disk drive.
It is not recommended to put the Unity Project in a folder that will be backed up to the cloud as that
can cause unexpected errors during development (such as locked files and other random errors)!
Project Setup
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:
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.
And then modify Pixel Per Unit and Filter Mode Settings in the Inspector:
Note: this tells Unity how to load the image, which compression to use (none in our case), use Point filtering
(this avoids weirdness) 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:
Note: Make sure the Hexagon Pattern is not part of the Main Camera. Try to drag and drop it into a empty
part of the Inspector.
So far, so good, but we're not done yet. Get ready for the next mission!
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. Select hexagon_pattern and We can change the hexagon
pattern's Sorting Layer if we take a look at the Additional Settings component in the Inspector:
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:
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:
Save your work. A good game developer will regularly save their work to prevent data loss. You
can go to File -> Save or press Control + S together (Command + S on Mac OS) to save the scene.
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:
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:
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:
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:
Afterwards we can take a look over to the Inspector and select Add Component -> Physics 2D ->
Box Collider 2D:
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/Paddle
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:
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:
Now we can drag the Racket from the Project Area into the Hierarchy and position it on the bottom
of our game:
Note: You can also set the Transform XYZ Values directly by using the Position set of values in the Rackets'
inspector if you're having trouble aligning it up. A suggested value for those are: X 0, Y -95, Z 0.
Save your work.
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:
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 set the following settings:
- Gravity Scale: 0 (prevents the racket from falling out of bounds)
- Collision Detection: Continuous (prevents glitches where the ball might clip through the racket
due to Physics 2D engine quirks)
- Freeze Rotation on the Z Axis: this makes the racket freeze its angle. Leaving this unticked can
cause the racket to spin on the Z axis when the ball collides with the racket, which can be quite
amusing at first but it would soon become very annoying.
Congratulations on making it this far! Don't forget to save your work. We're just over halfway there.
Racket Movement
The player should be able to move the racket horizontally. This kind of feature can be added
with Scripting. Let's select Racket from hierarchy tab and click on Add Component -> New
Script in the Inspector, name it Racket and click the "Create and Add" button:
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:
Let's open the Script by double clicking it. This should bring up Visual Studio or another code editor
if you are on a different platform. Here is how it looks:
using UnityEngine;
using System.Collections;
}
}
Our Start function is automatically called by Unity when starting the game. Our Update function is
automatically called over and over again, roughly tied to the game frame rate which is set to 60 by
default.
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-related calculations, as our Racket is
a Physics object (since it has a Rigidbody).
We can remove the Start and Update functions and create a FixedUpdate function now:
using UnityEngine;
using System.Collections;
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:
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, also known as netural position 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");
Note: we access the Rigidbody2D component that we attached to our Racket 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:
The Ball
The Ball Image
It's time to add the Ball. Like before, we will begin by drawing some kind of ball imaginable:
Note: right click on the image, select Save As... and save it in the project's Assets/Sprites folder.
We will use the following Import Settings for the ball image:
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:
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 -> Physics Material 2D and name it BallMaterial:
Afterwards we can take a look in the Inspector and adjust the material properties in order to make it
bounce off:
Now we just have to drag the material from the Project Area into the Material slot of the Ball's
Collider:
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 the Create and
Add button. We will also move it into our Scripts folder in the Project Area and then open it:
using UnityEngine;
using System.Collections;
}
}
}
}
Let's use the Rigidbody's velocity property to make it move upwards by a certain speed:
using UnityEngine;
using System.Collections;
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;
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);
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.
Note: Use the same values as shown here for the Green, Pink, Yellow and Blue block sprites.
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:
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:
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 click the "Create and Add" button. We will move it into our Scripts folder again as
shown previously and then open it:
using UnityEngine;
using System.Collections;
}
}
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;
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:
We will repeat this process for each of the different block color images in our Project and with all
block of different color block we will attach same script as it was with block_red.
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:
Save your work. You don't want your hard work being undone by a sudden Unity crash or some
other failure. Congratulations, you've completed your own 2D Arkanoid Game!
References
TutNoob. (n.d.). Retrieved from https://noobtuts.com/unity/2d-arkanoid-game