Unity First Person Shooter (FPS) Game
Foreword
In this Tutorial we will learn how to make a First Person Shooter (FPS) game in Unity. As usual, everything will be as simple as possible.
We will focus on the following First Person Shooter elements:
- WSAD-Movement & Jumping
- Looking around with the Mouse
- A decent looking weapon
- Bullets that explode on impact
- A decent looking level
- Something to shoot at
Now the 'movement' and 'looking around with the Mouse' parts sound like a lot of crazy math. But as usual Unity takes care of this for us. We will end up with only 50 lines of code for the game (which is... crazy).
Video Preview
Here is a video of the final game:
Requirements
Knowledge
This tutorial requires some understanding of the Unity basics. Take a look at our easier Unity Tutorials like Unity 2D Pong Game in case you never used Unity before.
If you already know the Unity basics then it's time for us to get started. Remember: it's easy!
Unity Version
We created this game with Unity 4.5.1f3, but any newer version should do just fine too.
We won't make use of any advanced features so Unity's free version is all that's needed.
Art Style
We will design our game with something like Quake in mind. Our Art Style should be easy to create and yet give some nice looking effects. We will use a lot of transparency to get the futuristic effect that we can see in the preview picture at the top of this tutorial.
Project & Scene Setup
We will begin by creating a new Unity project via File->New Project.. in a directory like C:/unity_fps. We will also import the Character Controller and Particles packages as shown below:
Note: the Character Controller package will be used for movement and mouse looking, the Particles package will be used for explosions.
Afterwards we save it once via File->Save Scene with the name "scene_main" (without the "").
Note: a saved scene simply contains everything that is in the Hierarchy.
The Level
A good FPS game needs a good looking level.
We decided to create a nice looking 3D model for our level:
While we provide the level as download for Premium members, we still encourage you to create one on your own with Unity's primitives (see the top menu: GameObject->Create Other->Cube/Sphere/Capsule/Cylinder/Plane).
Simply start with a plane (as ground), add some cubes (as walls) and put textures on them. If you take your time you can create a decent looking level very easily.
Movement and First Person Camera
Adding the Controller
Now let's jump right at the most complicated part of every First Person Shooter: implementing WSAD-movement in combination with a proper first person camera.
Those who ever tried to do that on their own will understand how much of an achievement Unity's First Person Controller is. It takes care of all the math and allows us to add WSAD-movement with a first person camera in just a few mouse clicks.
We can find Unity's First Person Controller in our project area under Standard Assets:
Let's drag it into the Hierarchy:
And position it so it's in our level:
This would be a bad position because it's outside of the level:
Small Adjustments
We need to make three little adjustments to our First Person Controller.
First off, our Hierarchy currently has two Cameras. One is part of the FPS Controller and one was there by default:
We don't need the one that was there by default, so let's delete it (the one that is NOT part of the First Person Controller, which is the lower Main Camera in our picture).
Let's select the Main Camera that is still in the Hierarchy and take a look at the Inspector. Here we will change the Background color to black (choose whatever you like) and we disable the Mouse Look script:
Note: there is one Mouse Look script attached to the 'First Person Controller' and there is one more which is attached to the 'Main Camera' (the one that we just disabled).
The first one is taking care of the horizontal mouse-looking, the other one takes care of the vertical mouse-looking.
We disabled the vertical mouse-looking because it's a neat game design decision. It requires the player to jump if he wants to fire at higher targets.
If we press the Play button we can already move with the W, S, A and D keys, jump with SPACE and use the mouse to look around.
Now that was really easy, considering how much crazy math would be required to do that manually.
Weapon
The Plan
Okay so let's give the player a weapon. As usual we could create a fancy 3D model, which is complicated. Or we can use Unity's primitives with a few textures on them.
Here is how the final weapon will look like:
Our game being a first person shooter makes our lives a lot easier here. The player only sees the upper-left part of the weapon, so we might as well leave all other sides away entirely.
The Weapon GameObject
Let's create an empty GameObject via GameObject->Create Empty and name it weapon. This will be the parent (or in other words: container) for the weapon model parts.
We want the weapon to be attached to the player so it changes its position whenever the player's position changes. This is very easy due to Unity's Hierarchy. All we have to do is make the weapon a child of the Main Camera by dragging it onto the Main Camera:
Now the weapon always moves and looks where the player moves and looks.
The Primitives
Let's create the weapon model. We create three cubes via GameObject->Create Other->Cube and then we move them into the weapon GameObject in the Hierarchy:
Now all we have to do is position, rotate, scale and put a texture on them so they look like the upper-left part of a weapon:
Positioning it properly
The tricky part is to position the whole thing in a way that it looks like it's in the Hand of the player. Here are the properties that we used to achieve the effect:
weapon GameObject:
Cube 1 GameObject:
Cube 2 GameObject:
Cube 3 GameObject:
This is the transparent texture that was used:
Note: it's really small but it's there. Try to right click it and save it in your project folder, or create your own texture.
After putting the texture onto the cubes we can select the Unlit/Transparent shader to see the transparency in Unity:
If we press play then we can now see the weapon being perfectly positioned. So far so good!
Rocket Shooting
The Model
Yet again we will use Unity's primitives to create a Rocket model:
This time we don't want to have the Rocket in the Hierarchy all the time. Instead we drag it from the Hierarchy into the Project area, which creates a Prefab:
Afterwards we delete the Rocket from the Hierarchy. We still want it to be in the Project area though.
About Physics
We want the rocket to be 'a Physics thing'. It should be able to collide with walls (or players) and we need a way to make it fly forward as soon as the player shoots it.
We can achieve both effects by simply adding a Rigidbody to the rocket via Component->Physics->Rigidbody. We will give it the following properties:
Note: we freeze the rotation because the rocket should simply fly forward without spinning in the air or anything. The other parameters are more or less fine-tuning.
Exploding on Impact
Let's create a script so we can find out when the Rocket hit something. We right click in the Project area, select Create->C# Script and name it Rocket. Our script only needs two public variables and one function:
using UnityEngine;
using System.Collections;
public class Rocket : MonoBehaviour {
// The fly speed (used by the weapon later)
public float speed = 2000.0f;
// explosion prefab (particles)
public GameObject explosionPrefab;
// find out when it hit something
void OnCollisionEnter(Collision c) {
// show an explosion
// - transform.position because it should be
// where the rocket is
// - Quaternion.identity because it should
// have the default rotation
Instantiate(explosionPrefab,
transform.position,
Quaternion.identity);
// destroy the rocket
// note:
// Destroy(this) would just destroy the rocket
// script attached to it
// Destroy(gameObject) destroys the whole thing
Destroy(gameObject);
}
}
The OnCollisionEnter function will be called by Unity whenever the Rocket collides with something. All that's left for us to do is Instantiate the explosion and then Destroy the rocket itself.
This is how our Rocket Prefab looks in the Inspector after adding the script to it (by dragging it on there):
Now it's time for an Explosion. Yet again Unity helps us out. We already imported Unity's particles when creating the Project, and those already contain an Explosion effect that is perfectly fine for us.
So let's take a look in the Project area under Standard Assets->Particles->Legacy Particles and drag the Small explosion Prefab into the Explosion Prefab slot of our Rocket script so it looks like this:
Just one more thing: by default the Explosion would explode over and over again so let's select the Small Explosion prefab in the Project area and enable the One Shot option:
We just finished the Rocket. We will be able to see it in action very soon!
The Shoot Script
Alright let's create a new C# Script again, this time we will call it Shoot. This script is supposed to spawn a new Rocket whenever the player does a mouse click. It then uses the Rigidbody's AddForce method to make it fly forward:
using UnityEngine;
using System.Collections;
public class Shoot : MonoBehaviour {
// Rocket Prefab
public GameObject rocketPrefab;
// Update is called once per frame
void Update () {
// left mouse clicked?
if (Input.GetMouseButtonDown(0)) {
// spawn rocket
// - Instantiate means 'throw the prefab into the game world'
// - (GameObject) cast is required because unity is stupid
// - transform.position because we want to instantiate it exactly
// where the weapon is
// - transform.parent.rotation because the rocket should face the
// same direction that the player faces (which is the weapon's
// parent.
// we can't just use the weapon's rotation because the weapon is
// always rotated like 45° which would make the bullet fly really
// weird
GameObject g = (GameObject)Instantiate(rocketPrefab,
transform.position,
transform.parent.rotation);
// make the rocket fly forward by simply calling the rigidbody's
// AddForce method
// (requires the rocket to have a rigidbody attached to it)
float force = g.GetComponent<Rocket>().speed;
g.rigidbody.AddForce(g.transform.forward * force);
}
}
}
As explained in the code's comments, the only interesting part here is the transform.parent.rotation thing. It's there to make the Rocket fly exactly forward (exactly in the player's forward direction). If we would use transform.position it would make the Rocket fly exactly forward in the weapon's forward direction - but the weapon is rotated a bit to the left, which would make the Rocket fly a bit to the left too.
Now we save the script, add it to the weapon and drag the Rocket Prefab from the Project area into the Rocket Prefab slot so it looks like this:
There is one little adjustment to be made before we can test it. Right now if the player clicks the mouse button, a Rocket would spawn exactly where the Weapon is and then fly forward into the Player's forward direction. But we told the Rocket to explode whenever it hits something - and since it spawns exactly where the weapon is, it would hit the weapon immediately.
We can easily prevent this by disabling (or removing) all Collider components that are on our weapon or on the children of it (the cubes).
If we press Play, we can now run around and shoot Rockets at things:
We just finished the core mechanics of our Unity First Person Shooter!
Bull's Eyes
Let's make the game a little bit more fun by adding a few Bull's Eyes that can be used for shooting practice.
As usual we will start by creating the model with Unity's primitives:
Here is the Bull's Eye texture that we used:
Now we add two empty GameObjects to the Scene which define the left and right points (the Bull's Eye is supposed to move back and forth between them):
Afterwards we create a little BullsEye script that takes care of the back-and-forth movement:
using UnityEngine;
using System.Collections;
public class BullsEye : MonoBehaviour {
// left and right marks
public Transform left;
public Transform right;
// speed
public float speed = 1.0f;
// current direction (false means to the left, true means to the right)
bool dir = false;
// Update is called once per frame
void Update () {
if (dir) {
// go closer to the right one
transform.position = Vector3.MoveTowards(transform.position,
right.position,
Time.deltaTime * speed);
// reached it?
if (transform.position == right.position)
dir = !dir; // go to opposite direction next time
} else {
// go closer to the left one
transform.position = Vector3.MoveTowards(transform.position,
left.position,
Time.deltaTime * speed);
// reached it?
if (transform.position == left.position)
dir = !dir; // go to opposite direction next time
}
}
}
The interesting part here is the dir variable. If dir is true then the Bull's Eye moves towards the right point. If dir is false then it moves to the left point. It inverts the value of dir whenever it reached a point.
Now we just add the script to the Bull's Eye model, drag the left and right points into the left and right slots and that's it.
Now the Bull's Eye moves back and forth between the two points like shown in the Video at the very top of this tutorial.
Summary
As usual there are all kinds of improvements that can be made, like hiding the cursor or adding sounds, menus, options, enemies or a Trail Effect for the Rockets like this one:
We just created a very robust, fast and most importantly: simple FPS game in Unity. And the result is definitely nice to look at:
Download Source Code & Project Files
The Unity First Person Shooter (FPS) Game source code & project files can be downloaded by Premium members.All Tutorials. All Source Codes & Project Files. One time Payment.
Get Premium today!