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.

4.9 (8) · 2 Reviews

Download materials
Save for later
Share

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 classic Invaders arcade game.

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!

Note: This tutorial assumes you already have basic experience with Unity and an intermediate knowledge of C#. Additionally, this tutorial assumes you’re using C# 7 and Unity 2020.3.

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.

The starting point shows the cannon, the score and the number of lives.

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 Physics2D Layer Collision Matrix

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.

The project's Hierarchy window

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.

The Game Controller GameObject's Inspector window

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.

The Music GameObject in the Inspector window

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.

The Inspector for the CANNON component

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 by speed * 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.

The cannon is now able to move via the A and D keys.

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 by speed * Time.deltaTime every frame toward the top.
  • Use DestroySelf to destroy the bullet GameObject. Before calling Destroy, you disable the bullet because destruction takes some frames to process but disabling is almost instantaneous.
  • Awake invokes DestroySelf to destroy the bullet automatically after lifetime 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.

The Inspector window for the Bullet prefab.

Now, select Game Controller from the Hierarchy. Set Game Manager‘s Sfx to the Audio Source attached to the Game Controller.

Inspector window showing Game Controller's Audio Source component.

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.

The Cannon Control component in the Inspector window

Save and Play. Now you can move the cannon and shoot laser bullets by holding down the Space key.

The cannon can now shoot laser bullets.

Your hero is ready! Now it’s time to add villains. In the next section, you’ll add the invader swarm.