Unity Tutorial: How to Make a Game Like Space Invaders
In this Unity tutorial, you’ll learn how to make a classic 2D space shooting game similar to Space Invaders. By Najmm Shora.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Unity Tutorial: How to Make a Game Like Space Invaders
40 mins
Space Invaders, known in Japan as Supēsuinbēdā (スペースインベーダー), is one of the most well known retro games in the world. Released to arcades in 1978 by the Japanese game company Taito, it quickly became a massive hit.
The laser bullet-shooting cannon represents the player. The player can hide behind any of four torchka (トーチカ), also known as a pillboxes.
There are three types of invaders: crab, squid and octopus. They appear in a swarm of multiple rows and move from the top to the bottom of the screen. The crab invader has become an iconic symbol universally associated with arcades and games in general.
The game’s objective is to eliminate the invaders before they reach the bottom of the screen while dodging and hiding behind torchkas. In addition to the swarm, there’s also a UFO that appears from time to time. However, you’ll focus on the swarm.
In this tutorial, you’ll replicate the core gameplay features of Space Invaders using Unity. Along the way, you’ll learn how to:
- Spawn and move the invader swarm.
- Make the invaders at the swarm’s head shoot laser bullets.
- Move and shoot back as the player.
- Change the music tempo and swarm speed based on kill-count.
Time to get started!
Getting Started
Download the project materials by clicking the Download Materials button at the top or bottom of this tutorial.
Extract the zip file to a convenient location. After extracting, you’ll notice Starter and Final project folders. Open Starter in Unity.
The project contains some folders to help you to get started. Open Assets/RW and you’ll find the following directories:
- Animations: Contains pre-made animations and the animator for the bullet and explosion prefabs.
- Prefabs: Has all the prefabs the project uses.
- Resources: Contains fonts and textures.
- Scenes: Contains the main scene you’ll work with.
- Scripts: Has all the project scripts. Most of them are empty shells which you’ll fill.
- Sounds: Has all the sound effects and the music file.
- Sprites: Contains all the pixel art for the project.
Navigate to RW/Scenes and open Main. Click Play and you’ll see the red player cannon in the bottom center of the screen and hear the music loop. In addition, you’ll see the Score and Lives UI labels.
You can’t interact with the game yet, but you’ll add the interactivity in this tutorial.
Stop the game and select Edit ▸ Project Settings ▸ Physics 2D. Take a look at the Layer Collision Matrix. Notice this project has two custom layers: Hero and Enemy.
The Physics 2D collision detection for GameObjects in the Enemy layer only work with GameObjects on the Hero layer. Hero layer GameObjects work for both Enemy and other Hero layered GameObjects. This information will be important later.
Now, take a look at the GameObjects in the Hierarchy. Some have custom components attached that you’ll work on in this tutorial.
Game Controller has Invader Swarm, Torchka Manager and Game Manager components attached. In addition to these, there’s an Audio Source component you’ll use for the sound effects.
Music has Music Control and an Audio Source. The Audio Source plays Beats located in RW/Sounds. This is the game’s main music. Currently, the music has a fixed tempo, but later you’ll make it dynamic.
CANNON has Cannon Control and a Box Collider 2D for collision detection. Notice its layer is set to Hero. It also has two immediate children: Sprite, which is its associated sprite, and Muzzle, an empty GameObject that represents the position for bullet instantiation while shooting.
Main Camera is the game’s main and only camera and has the Audio Listener. It’s orthographic with a position offset of -10 along the Z-axis.
All the other GameObjects have Z set to 0. In fact, for the others, assume the Z-axis doesn’t exist since this is a 2D game, and you’ll stick to positioning them only on the X and Y axes.
INVADERS Spawn Start and TORCHKA Spawn Center are two empty helper GameObjects parented to Helpers. Their positions will help you spawn the invader swarm and torchkas later on.
Canvas and Event System are for the UI. Canvas has the following children:
- Score Text: This displays the score.
- Lives Text: You’ll use this to display the remaining player lives.
- Game Over Panel: This panel displays the Game Over message when a player runs out of lives.
- All Clear: You’ll use this panel to display the All Clear message when the player eliminates all the invaders.
- Restart Button: This button restarts the game.
Now that you’re done with the tour, it’s time to add the good stuff. :] In the next section, you’ll work on the player controls.
Implementing the Player Controls
Select the CannonControl script attached to CANNON. Open it in your code editor. Paste the following code inside the class:
[SerializeField]
private float speed = 500f;
private void Update()
{
if (Input.GetKey(KeyCode.D))
{
transform.Translate(speed * Time.deltaTime, 0, 0);
}
else if (Input.GetKey(KeyCode.A))
{
transform.Translate(-speed * Time.deltaTime, 0, 0);
}
}
Here’s a code breakdown:
- The variable
speed
controls the cannon’s speed. - Inside
Update
, you check if the player is holding down keys D or A. If the player holds down D, the cannon moves right byspeed * Time.deltaTime
every frame. If they hold down A, the cannon moves left by the same amount.
Save the file. Return to Unity and select Play inside the editor. Now you can move the ship using D and A.
Next, you’ll add the shooting mechanics by using the Bullet prefab inside RW/Prefabs.
Select Bullet and take a look at the Inspector.
The prefab has a Kinematic Rigidbody 2D component. It’s Kinematic because you won’t rely on physics to move the bullet, but instead translate it via a script.
The Rigidbody 2D‘s layer is set to Hero and it has the Box Collider 2D component for collision detection. There’s also a Bullet component which doesn’t do anything yet.
Open the Bullet script inside your code editor. Add the following code inside the class:
[SerializeField]
private float speed = 200f;
[SerializeField]
private float lifeTime = 5f;
internal void DestroySelf()
{
gameObject.SetActive(false);
Destroy(gameObject);
}
private void Awake()
{
Invoke("DestroySelf", lifeTime);
}
private void Update()
{
transform.Translate(speed * Time.deltaTime * Vector2.up);
}
private void OnCollisionEnter2D(Collision2D other)
{
DestroySelf();
}
In the code above, you:
- Use
Update
to move the bullet byspeed * Time.deltaTime
every frame toward the top. - Use
DestroySelf
to destroy the bullet GameObject. Before callingDestroy
, you disable the bullet because destruction takes some frames to process but disabling is almost instantaneous. -
Awake
invokesDestroySelf
to destroy the bullet automatically afterlifetime
seconds.DestroySelf
is also called when a bullet collides with another GameObject.
You’ll need sound effects during shooting. Inside RW/Scripts, open GameManager and add the following inside the class:
internal static GameManager Instance;
[SerializeField]
private AudioSource sfx;
internal void PlaySfx(AudioClip clip) => sfx.PlayOneShot(clip);
private void Awake()
{
if (Instance == null)
{
Instance = this;
}
else if (Instance != this)
{
Destroy(gameObject);
}
}
The above code turns GameManager
into a singleton, which ensures it only has a single instance at any given time. It also adds a utility method, PlaySfx
, which accepts an Audio Clip and plays it using the Audio Source sfx
.
To use the bullet, you need to instantiate it. Open CannonControl again and add the following after the declaration for speed
:
[SerializeField]
private Transform muzzle;
[SerializeField]
private AudioClip shooting;
[SerializeField]
private float coolDownTime = 0.5f;
[SerializeField]
private Bullet bulletPrefab;
private float shootTimer;
Then, after the earlier movement code inside Update
, paste:
shootTimer += Time.deltaTime;
if (shootTimer > coolDownTime && Input.GetKey(KeyCode.Space))
{
shootTimer = 0f;
Instantiate(bulletPrefab, muzzle.position, Quaternion.identity);
GameManager.Instance.PlaySfx(shooting);
}
This code increments shootTimer
every frame until it reaches coolDownTime
. If the player holds down the Space key, the code resets shootTimer
and instantiates the bulletPrefab
at muzzle.position
. It also plays the shooting
sound effect by using the PlaySfx
inside GameManager
.
Save everything and return to Unity.
Go back to the Bullet prefab. Notice the new fields for the Bullet component.
Now, select Game Controller from the Hierarchy. Set Game Manager‘s Sfx to the Audio Source attached to the Game Controller.
Select CANNON from the Hierarchy. In Cannon Control, first set Muzzle to the Muzzle Transform that’s CANNON‘s child. Then set Bullet Prefab to the Bullet found in RW/Prefabs. Finally, set Shooting to CannonBullet found under RW/Sounds.
Save and Play. Now you can move the cannon and shoot laser bullets by holding down the Space key.
Your hero is ready! Now it’s time to add villains. In the next section, you’ll add the invader swarm.