Welcome welcome to this unity space shooter 2d tutorial. Where we will be building this cool new space shooter game with unity game engine.

Here is a screenshot of the early prototype.

Unity space shooter

The great thing about this tutorial is you won’t need any space shooter assets. All the assets you will need already ship with unity. We will be using primitive sprites like triangles, circles and diamonds for our game.

What you will learn

In this tutorial there is a lot to learn. We will learn about c# scripts, UI, physics, quaternions, bullet spawning, enemy spawning, particle effects,post processing effects and score keeping. We use the c# scripting to control our player or space ship movement, we build a enemy script spawner to help us spawn enemy ships. Another script will govern our bullets. We use quaternions to control the rotation of our space ship around the center of our world. Particle effects for explosions and post processing effects to give us a bloom blur effect and spice up our flat shapes which unity give us.

Unity Space Shooter: Creating our project

Start off with a blank new 2d project.

Call it unity space shooter. Here you have your blank new project.

First thing we want to do now is start by creating some sprites for our game so go ahead and right click in Assets and create a new folder called sprites.

Inside of sprites we want to create 3 assets for our space shooter game. First a triangle for our ship. A diamond for enemy ships and finally a circle for the mother ship or death star. So to do this right click goto create->sprites then create your 3 sprites.

unity space shooter tutorial basic assets

You should have something like this now.

unity space shooter tutorial assets

Once created we need to turn them into prefabs which we can use, but before that let’s just build out our scene. So drag them into your scene start by just placing the mothership (circle) in the scene. With it selected zero out it’s co ordinates like this.

Next bring in your PlayerShip and place it slightly below the circle like this.

Next we need to just do some setup for our player and mothership. So on the PlayerShip object add the following components.

Change your Rigidbody2D body type from Dynamic to Kinematic.

Next we want to add a collider. So we will use a Polygon Collider 2D.

Click on edit collider and make sure your playership has a bounding box right around it like this.

Next set your player collider to be is trigger by checking this box.

If you hit play now your game should look like this.

So now what we need to do is create a unity 2d space shooter movement script for our player.

Unity space shooter movement script

So to start off we just need to create a scripts folder for our project. So go over to the assets folder right click and create a folder.

Call it scripts. Your folder structure if you have followed along should look like this now.

Double click into scripts and right click and go to create c# script.

Name your script Player.

Double click to open it up in visual studio. Here is the code we will be using to move our space shooter player.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Player : MonoBehaviour { private float rotationSpeed; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { if (Input.GetKey(KeyCode.Space)) { this.rotationSpeed = 10; } else { this.rotationSpeed = 50; } transform.RotateAround(Vector3.zero, Vector3.forward, Time.deltaTime * this.rotationSpeed); } }

So to explain how this script works. First we need a rotationSpeed to define how fast our player will be moving. For our player we will have a slow and fast speed at which we will move. So that we have some ability for the player to dodge ships. So in our update method we have a input where the player can press the space bar and make their ship move at a rotation of 10. Otherwise it will move at fast speed of 50. Then we take our player’s transform and we rotate it around Vector3.zero which is at the middle of our world, we then pass in Vector3 forward so that we rotation on the z-axis and then finally we pass in the speed at which our player must rotate multiplied by the Time.deltaTime variable to make our game frame independent.

So once you have created this script. Head back over into unity and drag and drop it onto our PlayerShip like so.

Now go ahead and hit play. Then you should have something that functions like this.

Great so we got moving ship or player now. Next we want to give our player the ability to shoot a bullet. So in order to do this we need to create the bullet.

Unity space shooting game: How to create bullets

To create our bullet we want to go ahead and create a 4th sprite in our sprites folder. This will be a square. So go into your sprites folder right click->create->sprites and click on square.

Rename it and call it bullet.

Next drag it into your scene so that we can resize it to look more like a bullet.

Resize it to about this big in relation to our player ship.

We now want to add a Rigidbody2D to our bullet and a Box Collider 2D. So click on your Bullet. Then click on add component.

Then add the rigidbody and the collider. Make sure to replicate these settings for your bullet.

Now we need to do two things to get our bullet to work correctly. We need a bullet script and then we need to modify our player script to be able to trigger off a bullet. So first let’s code up our bullet script. To do this go back into your Scripts folder and right click->create->c# script. Call it bullet.

Open it up in visual studio. Here is the code we going to use. I will explain it further below.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class Bullet : MonoBehaviour { public float sceneradius = 15; // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { if(transform.position.x < -sceneradius) { Destroy(gameObject); } if (transform.position.x > sceneradius) { Destroy(gameObject); } if (transform.position.y < -sceneradius) { Destroy(gameObject); } if (transform.position.x > sceneradius) { Destroy(gameObject); } } }

For now all this script does is just helps with clean up when we shot our bullet. So it has a scene radius, which just tells unity how far our bullet may travel before we destroy the object. Save that up and add it to your bullet like so.

Go back into your assets and create a folder called prefabs.

Open up your prefabs folder and drag your bullet from your Hierarchy to your prefabs folder. To end up with this.

Awesome so that is our basic bullet setup. We next need to create a placeholder for where we will be firing from. So we will add this to our player so that this point can follow our player as it moves.

Unity space shooting game: Muzzle setup

To create a muzzle from where our player will shoot bullets you need to start off by creating a empty game object which is a child of our player. So in the hierarchy click on the playership and right click and create empty game object.

Rename it to be muzzle.

We now want to click on it and drag it to the position just in front of our player ship like below.

Now the muzzle will follow the player as it rotates around the mother ship. Next we want to modify our player script to fire a bullet. So open up your player script.

Unity space shooter game: Spawning a bullet

In our player script we want to add the following bits of code.

public GameObject bullet; public GameObject muzzle;

Declare a placeholder for our muzzle and bullet so we can use them in our player script.

Next we want to spawn our bullet and give it a force so that it gets fired off.

if (Input.GetMouseButtonDown(0)) { Instantiate(bullet, muzzle.transform).GetComponent<Rigidbody2D>().AddForce(muzzle.transform.position * -10, ForceMode2D.Impulse); }

Add this bit of code to our update method. This will basically take a bullet spawn it at the muzzle position. Then use it’s rigidbody to add a force to it. ForceMode2D.Impulse will give us that immediate force. Save your player script. Then head back into the hierarchy select your PlayerShip and in the inspector you should now see this.

Drag the muzzle from the hierarchy into the muzzle slot and the Bullet from your prefabs folder into your Bullet slot. Like this.

Go ahead and run your game and you should now be able to fire bullets like this.

So there we now have a player which can shoot a bullet at the mother ship or death star. Next we going to have our mothership start spawning us some enemies.

Unity 2d space shooter: Spawning Enemies

Go over to the Assets->Sprites folder select EnemyShip and drag it into your game scene.

For our EnemyShip we want to add two components. One a RigidBody2D and a Circle Collider 2D. Add them by clicking on EnemyShip and in the Inspector click on add component to add those two components. Copy these settings for the collider and rigidbody.

Once done you can go ahead and create a new c# script called EnemyShip in your scripts folder. Drag it onto your EnemyShip like this.

Open it up in visual studio. Here is the code we will be using for the ship.

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class EnemyShip : MonoBehaviour { public float bounds; // Update is called once per frame void Update() { if (this.transform.position.x > bounds || this.transform.position.x < -bounds || this.transform.position.y > bounds || this.transform.position.x < -bounds) { Destroy(gameObject); } } }

So very simple for now we just going to declare a bounds like we did with our bullet on how far the ship can travel before being out of the scene. We then simply check if it’s out of our scene then destroy the ship if it is. Save that up and now we going to create a EnemySpawner. First before we can do that drag your EnemyShip into your Prefabs folder to make it a prefab.

Next go to your hierarchy and right click to create a empty game object. Call it EnemySpawner. It should look like this.

We now need to create a enemy spawner script. So go ahead and create a new c# script in your scripts folder called EnemySpawner and drag it onto your EnemySpawner.

Open it up in visual studio and copy and paste this code in there.

using System.Collections; using System.Collections.Generic; using UnityEngine; public class EnemySpawner : MonoBehaviour { float timer = 0.0f; float randtime; public GameObject spawnPoint; public GameObject enemy; // Start is called before the first frame update void Start() { randtime = Random.Range(0.5f, 2f); } // Update is called once per frame void Update() { if(timer > randtime) { GameObject ship = Spawn(); Vector2 dir = (Vector2)(Quaternion.Euler(0, 0, Random.Range(0f, 360f)) * Vector2.right); ship.GetComponent<Rigidbody2D>().velocity = dir * Random.Range(200f, 400f) * Time.deltaTime; randtime = Random.Range(0.1f, 0.2f); timer = 0.0f; } timer += Time.deltaTime; } GameObject Spawn() { return Instantiate(enemy, spawnPoint.transform.position, Quaternion.Euler(0f, 0f,0f)); } }

Explaining the code and Euler and Quaternions

So this script is a little more complicated because we are using Quaternions. The scope of what a quaternion is, is beyond the scope of this tutorial, but in short a quaternion is a vector which represents and angle. Then Euler is a way of taking a vector of rotations into a directional vector.

So explain the script we start off a timer to keep track of time passed.

A randtime to store a random spawn time.

SpawnPoint to give our spawner a position to spawn from.

Enemy game object for dropping in our EnemyShip prefab.

So in our start method we start off with a random range for the amount of time which needs to pass for our enemy to spawn. In our update method we check if our timer has exceeded our random time. Then we know it’s time to spawn an enemy again in our scene. We call a spawn function which essentially instantiates our enemy at the spawn position with a 0 angle. From here we then calculate a random direction between 0 – 360 degrees on our z axis.

After this we get our rigidbody and set its velocity in the direction we calculated multiplied by a random velocity between 200 and 400 and multiply it by deltaTime to manage our frame rate.

Finally we get a new random time, set our timer back to 0. After if statement we just keep adding our deltaTime to our timer to keep the timer ticking throughout.

This may seem very complicated, but try this script out and modify it a little bit and experiment to see what results you can produce with it.

Final steps to making this work we need to assign our objects. So save the script and head back into Unity and click on EnemySpawner. Drop your Mothership in spawnpoint and your EnemyShip prefab into your Enemy slot like this.

Give it a run and you should now have this.

Go and resize your enemies down to make sense for your scene. I am going to do the same.

Killing the player

Now we need to look at how our enemies can kill our player when they collide with our player. So to do this we need to use an EventHandler called OnTriggerEnter2D. So we will be modifying our player script. Before we do that we need to do a few things to make sure we can detect exactly what is colliding with what. So head into your hierarchy and click on the PlayerShip object.

Then on the right in the inspector you want to tag this game object as your player. So on the right you need to toggle this option.

Next go into your prefab and click on EnemyShip.

Click on add tag like this.

Then on this screen click on the plus.

Save as Enemy.

Click back on EnemyShip and select Enemy from the drop down. Like this.

While we are tagging objects let’s tag our bullet as well so open up your Bullet prefab and add a bullet tag with the same method as with our Enemy.

Do the same with the Mothership. By tagging it like this.

That should be all the tags you would need to complete the collider detection and identification for the rest of the game. So let’s now look at how we can kill the player.

To kill the player simply go into the Player script and add this code.

private void OnTriggerEnter2D(Collider2D collision) { if (collision.tag == "Enemy") { Destroy(gameObject); } }

This will basically check if the colliding object is a object tagged as enemy, if so destroy our player. If you have done everything correctly your game should work like this now.

Unity space shooting game: Killing enemies with bullets

Next up we need to kill our enemies with our bullets, so this again is going to require a ontriggerenter2d event. Go ahead and open up your EnemyShip script. You want to add this piece of code to your script.

private void OnTriggerEnter2D(Collider2D collision) { if (collision.tag == "Bullet") { Destroy(gameObject); } }

Very simple if a trigger gets triggered where the collider was a bullet destroy our EnemyShip gameObject.

Before this works properly we need to just make some adjustments to how unity detects collision. Otherwise our bullets will just pass through our enemy.

Goto your EnemyShip prefab and turn on continous collission detection.

Click on your bullet prefab and do the same.

If you hit play on your game you should now have something like this.

Creating some effects, post processing

Let’s now give our game some life with post processing effects. To do this we need to import the post processing package into unity. Go over to window->package manager.

Search for post processing.

Click on install.

Once installed click on your main camera. Then add component post process layer.

Change layer to Everything for now. We will later add it to it’s own layer.

Now we need to create ourselves a volume. So to do this create a new empty game object in your hierarchy and rename it to Post-process Volume.

Click on the post process volume and add a new component called post process volume.

Once done check is global and click on new to create a new volume profile.

Click on add effect->unity and add the following effects.

Bloom

Chromatic Aberration

Color Grading

Motion Blur

Vignette

Grain

Depth of Field

Here are all my settings. Copy them as is.

After all this you should have something nice looking like this.

Let’s just go ahead and fix up the scaling of our game let’s make our enemies smaller and our player ship. To something more like this.

Great let’s add a few more effects.

Creating a basic explosion particle system: Unity shooting game

Let’s create our particle system. In your hierarchy right click and click effects->Particle System.

You should have something doing this.

Rename it explosion.

Copy my settings I have below. For your start color you can use whatever you like but copy the other settings.

Once done drag it into your prefabs folder like below.

We now want to add this to our bullet script by adding this code to our bullet script. So go and open up bullet.cs in visual studio.

public ParticleSystem explosion; private ParticleSystem explode;

private void OnTriggerEnter2D(Collider2D collision) { if (collision.tag == "Mothership") { explode = Instantiate(explosion); explode.Play(); Destroy(gameObject); } }

Setup your mothership. Click on it on the left hand side and add these components with these settings there.

Next we need to add our particle system to our Bullet prefab. So open up your bullet prefab.

Drag your Explosion prefab into this slot.

If done correctly you should now end up with this when you shoot the mothership.

Particle System Pro Tip

If your particle system is not destroying it self after it has played. Then open up your particle system prefab again and check this box.

Now the last thing to do is give our game a score ui element. So we can keep score.

Keeping score: Unity 2d shooting game

In order to keep basic score we need to introduce a singleton design pattern for keep our state in our Game. To do this we want to create a Game c# script in our scripts folder like this.

Open it up in visual studio and copy and paste this code in there.

using UnityEngine; public class Game : MonoBehaviour { int Score; static Game Instance; void Awake() { if (Instance == null) Instance = this; else Destroy(this.gameObject); } public static void AddToScore(int points) { Instance.Score += points; } public static int GetScore() { return Instance.Score; } }

So how this code works is, it makes sure we can only create a instance of this Game class once and only once. So that we never lose a reference to this class in our Game. We have a AddToScore method which helps us keep track of points. To have this script run when our game runs we want to create another empty game object called GameManager. So go back to unity and right click in the hierarchy to create a empty game object.

Drag your Game script onto the GameManager like this.

So this will now make our Game object available globally in our code base. So we can now do something like this.

if (collision.tag == "Bullet") { Game.AddToScore(1); Destroy(gameObject); }

Open up your EnemyShip script and make sure you have that code in there. So this will basically destroy a ship and add 1 to our score if we kill a ship.

Save that off. Let’s now create a UI element to show our score on screen.

Go to the unity editor and in the hierarchy right click UI and create a new Canvas. Then click on Canvas and right click UI and click on Text.

Click on your Text and in the inspector on the right. In the field text just type a 0.

Here are the exact settings I used in my project.

You now want to go to your Text object again and position it in your scene like this using the move tool.

So once sized and positioned you might end up with something like this.

Our score is all blurry and being effected by our post processing effects. To fix this we need to move our UI in front of our post processing. So click on the Canvas gameObject and click on this button.

To switch into 3d mode. You should see this once you did this.

Use the move tool.

Drag the blue arrow to the left to move our canvas in front of our Post process volume.

Select all your other objects and drag them to the right to move them behind our UI.

Should now end up with this if you player your game.

Unity top down shooting game: UIManager Singleton Setup

Great now to finish off to be able to update our score on our game we need the UIManager script. So go ahead and create the UI manager c# script in your scripts folder.

Copy and paste this code to use for your UI manager.

using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class UIManager : MonoBehaviour { public Text scoreText; static UIManager Instance; void Awake() { if (Instance == null) Instance = this; else Destroy(this.gameObject); } // Update is called once per frame void Update() { scoreText.text = Game.GetScore().ToString(); } }

Save that off go back to unity and click on your Canvas and drag your UIManager onto the Canvas.

Drag your text object to the Score Text slot.

If you have followed along and you player your game now you should have a unity shooter game :). Which looks something like this.

Final Words

If you enjoyed this tutorial. Consider sharing it on social media with your friends and following. If you want to support me financially. Check out my course in the right hand bar where I link through to my Unity course on building a 3d city builder. Also please subscribe to my YouTube channel if you prefer watching video tutorials and are interested in following my dev logs. If you are interested in more Unity tutorials. Check out some of these tutorials below.