Recreating Asteroids with Unity — Part 1

Alessandro Valcepina
7 min readApr 13, 2020

--

A simple tutorial on re-creating the classic Asteroids with Unity

Welcome back fellow aspiring Unity developers!
If you enjoyed my previous post, get ready for more, because we are going to re-create another old times classic!
If, on the other hand, you don’t know what I am talking about, be aware that you can find the previous tutorial in this series here.

Now, before we start, I want to remind you that this project has been developed using Unity 2019 and that you can always check the full source code on github. Mind the fact that, this time, the git repository does not include the assets, which are anyway freely available from the assets store and can be easily replace with different ones.

Asteroids

Let’s start by refreshing our memory. What is Asteroids?
Asteroids is a very famous arcade game, developed in 1979, in which the player takes control of a spaceship and has to shoot down lots of asteroids that are travelling across the screen, trying at the same time to avoid any collision.
You can see the original gameplay in the video below.

Designing the game

The plan is simple. We want a gameplay similar to the original one: our ship should be able to turn around and move freely and, at the same time, shoot asteroids that come randomly from the sides. Also leaving the field of view should move the ship to the opposite side of the screen.
Asteroids that are being hit should explode after a few hits and the ship itself should explode when hit by an asteroid.

As far as the UI goes we want to have at the very least a starting menu with some dynamic background and a game over screen. Also, while playing, we want to see the player score.

That’s it. Now that the goal is set and clear, we are ready to start!

The starship

We are going to start from our starship. You can use any model you like, but, for this tutorial, you can simply rely on any free asset from the assets store. In my project I have used UAV Trident.

Import the asset you’ve chosen and drag the ship prefab in the scene, taking care to reset its position. Now open the the UAV Trident ship select the default object and change its rotation to 0, 180,0, so that it is facing the correct direction.
Select again the Uav Trident game object and set the x axis rotation to -90. This is a temporary setting to allow you to test the ship at the end of this section. We won’t need it in the long run.

Now add the following PlayerController script to it.

At the top of the script we have a few fields for which we should provide values. In particular take note of the fact that you will need a laser prefab. For now simply create a small enough capsule with a red colored material and assign it to the field. As a quick reference, these are the values I used in my prototype.

Save the laser game object as a prefab and delete it before assigning it as a value for the script.

On the starship you can set Rotation Speed to 90 and Movement Speed to 150, but feel free to play around with the values to find the ones you prefer. The Cooldown field represents the pace at which lasers are being shot from the ship. In myproject I set it to 0.3.
As you can see in the Update method, we are allowing the player to control the ship via WASD keys and to shoot the laser by pressing the spacebar.
Now add a rigidbody to the ship and set its value like this.

In particular a 0.5 Drag will give the ship that “drifting behaviour” when you stop pressing a movement key.

We will also need two Capsule Colliders (or one capsule cinematic collider and a mesh collider if you prefer) with the following settings.

We will use the non cinematic collider for proper collision detection and the cinematic one to find the player more reliably (more on that later).

Obviously, once created by the PlayerController script, the laser is not gonna do anything on its own. Hence, we will need to add a LaserBehaviour script.

As you can see, the LaserBehaviour script, among other things, also contains the method OnBecameInvisible to destroy the laser when it exits the screen.
Don’t forget to set the Speed field value in the inspector. A value of 40 should do.

Now set the Main Camera to this position, so that it looks in the right direction, and you will be ready to test your ship’s movement.

The first asteroid

It’s now time to take care of the antagonist to our starship: the asteroids.
Once more, let’s a take a look at the Assets store and see what it has to offer in the way of asteroids. There are several free options, but, personally, I decided to go with this free Asteroid Pack.

Import the asset and drag the prefab of your choice into the scene.
Take note of the fact that the prefab comes with a script controlling the random rotation of the asteroid and with a rigidbody.
In the latter, set the mass to 1 and the drag to 0, so that we will have a easier time moving the asteroid around. Also freeze movement on the z axis.

After all is done, your rigidbody should look like this.

Add a new script to the asteroid and call it AsteroidController. For the time being it will be very simple and it will look like this.

The script simply adds a force to move the asteroid forward and implements the method OnBecameInvisible to destroy the asteroid once it leaves the viewing field.

Don’t forget to add a capsule collider to you game object, so that collisions with the ship and other asteroids will be handled.

Now add a 45 degrees rotation on the y axis to the asteroid and you should be able to see it moving by hitting play.

The Game Controller

As the last step for this first post, we need to add some sort of “glue” that will hold together all the pieces we created so far. That will be our Game Controller.
Create an empty game object and add a new GameController script to it.

For the script to compile we will also need to add another file containing the struct we will use to find the correct position where to spawn the asteroids.

Let’s go through the logic we just implemented, because it’s quite complex and requires explanation.
In the Start method we are instantiating the player prefab (aka the starship) and setting the screen center and screen boundaries. These are used later on, specifically in the InstantiateRandomAsteroid method, to instantiate asteroids just outside the viewing field so that they don’t just blink into existence. Take also note of the fact that in this method we are relying on an OverlapBox to avoid spawning two asteroids on top of each other.
All asteroids created by this method are sent flying towards the center of the screen and, potentially, across it, unless they meet another asteroid or the player on their paths.

The other interesting part of the script is the FindPlayer method, which is responsible to check whether the Player is still visible or not. One might argue we could have used OnBecameInvisible, just as we did for the laser and the asteroid, however this method has the problem that it will also consider the editor scene camera to verify visibility and, on top of that, I had some odd behaviour with it, while testing, so I decided to go with a more reliable, albeit more complex, solution.

Both InstantiateRandomAsteroid and FindPlayer are called in the Monobehaviour Update method. In here we check if the player is visible with FindPlayer and, if it is not, we calculate its new position on the other side of the screen. Then, if the timer is up, we spawn a new asteroid in a random position outside the view.

Now that the script purpose is clearer, let’s reset the position of both the Starship and the Asteroid (particularly the rotation) and save them as prefabs, then delete them.
You can now assign the newly created prefabs as values for the appropriate fields in the controller.
You can then set the other values to your liking, but, as a reference, I’m going to provide the values I used in my project. Keep in mind the scale values, particularly, can vary based on the asteroid you used.

Now, if you start the game, you should see something like this.

Great! We got most of the mechanics we wanted to implement!

Coming up next

We reached our goal for this tutorial, but the game is far from over. We need to handle several mechanics like collisions, death and scoring and of course let’s not forget about the current complete lack of an UI.
In the next post we will tackle all these issues and some more, in the meantime I hope you enjoyed this post and a bid you farewell!

--

--