noobtuts

Unity First Person Shooter (FPS) Game

unity-first-person-shooter

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:

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:
Unity First Person Shooter Imports

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:
Unity First Person Shooter 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:
Unity First Person Controller Prefab

Let's drag it into the Hierarchy:
Unity FPS Controller in Hierarchy

And position it so it's in our level:
Unity FPS Controller in Scene - Good

This would be a bad position because it's outside of the level:
Unity FPS Controller in Scene - Bad

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:
Unity Two Cameras in Hierarchy

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:
Unity FPS Camera in Inspector

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:
Final Weapon

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:
Weapon in Hierarchy

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:
Weapon Cubes in 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:
Weapon Model

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:
Weapon Properties

Cube 1 GameObject:
Weapon Cube 0 Properties

Cube 2 GameObject:
Weapon Cube 1 Properties

Cube 3 GameObject:
Weapon Cube 2 Properties

This is the transparent texture that was used: Transparent Weapon Texture
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:
Unity Unlit-Transparent Shader

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:
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:
Rocket 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:
Rocket Rigidbody

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):
Rocket in Inspector after Script

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:
Rocket in Inspector after Explosion

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:
Unity Small Explosion in Inspector

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:
Weapon in Inspector after Shoot Script

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:
Rocket Shooting

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:
Unity Bull's Eye

Here is the Bull's Eye texture that we used:
Bull's Eye

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):
Bull's Eye Left & Right Points

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:
Rocket Trail

We just created a very robust, fast and most importantly: simple FPS game in Unity. And the result is definitely nice to look at:
Unity FPS Game


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!