Introduction: How to Make Your First Virtual Reality Game for Beginners

About: My name is Matthew and I attend the University of Pittsburgh. Currently I am a senior, going for a bachelors in Information Science with a minor in CS. Current interests include augmented reality, virtual real…

This Tutorial will walk you through making your first virtual reality app with the Unity 3D video game engine and the GoogleVR plugin. This game will work for IOS and Android so it will run with traditional Google Cardboard headsets as well as the new Daydream VR headset. This will not require any previous experience with VR development or Unity 3D so I will try to make all the instructions as clear and beginner friendly as possible. The virtual reality game we will be making is a first person zombie shooter. The best part is, all the software we need to create this game is available for free.

I know I learn best through doing projects that I am excited about, thats why I created this tutorial. I will only be able to touch on a lot of the major concepts, so if you want to learn anything more in depth I suggest you do your own research on all the different pieces.

All the code and game assets can be downloaded here:

You can download Unity from here:

You will also need the GoogleVR SDK for Unity from here:

Step 1: Let's Set Up the Scene.

NOTE*****When installing Unity make sure to install the Android or IOS modules depending on what you need.

Once you have everything downloaded from the intro, create a new Unity project, and call it whatever you want.

Drag in the GoogleVR Unity package, the game assets folder, and the gun 3d model into the assets folder.

Go to file, build settings, and switch the build platform to either Android or IOS.

Delete the directional light from the scene.

Right click in the hierarchy (off to the left, where the light was) and create a 3d object, plane.

Drag the silver texture from the game assets folder onto the plane and off to the right where it says normal map choose the floor normal map. This adds not only a texture to our plane, but a normal map so Unity's lighting system knows how to reflect light off of our plane, giving the illusion of depth.

Right click in the hierarchy again and add a light, point light, and position it over top of our plane.

Now copy and paste this plane 4 times and position them as shown in the second image above.

Step 2: Complete the Scene.

Create another plane and add the brick texture to it as well as the brick normal map, the same as we did before. You will have to use the transform controls on the top right to rotate the plane until the brick pattern is facing the right direction.

Copy and paste this to make all the walls.

Select all of the floor planes and move them all up at the same time, rotate all of them so they are facing down to make the ceiling.

Right click in the hierarchy again and create a 3D object, cube. Add the wooden texture to it and the wooden normal map.

Copy and paste this a scatter a few around the scene wherever you would like.

Step 3: Bake Navigation Mesh.

Now the our scene is setup we can add our zombies. Before we do that though we need to consider how they are going to move around. Unity has built in pathfinding that we can use but first we need to bake a navigation mesh so our enemies know what areas that can and cannot move through.

Go back to the hierarchy and create an empty game object. Rename it scene and drag all your planes and cubes on top of it making them children. This will organize our scene. With that new scene object selected check the static box in the top right of the screen, to make all the children static.

Go to window, navigation, and a new window will appear to the right. Click bake in this window.

Now you will see our scene has a blue area overlaying all the walkable areas. This is our navigation mesh, our zombies are going to be the nav mesh agents, and our camera is going to be the nav mesh agent's destination.

This means that where ever we put a zombie in the scene it will walk across the navigation mesh towards its destination, avoiding all the areas not included in the mesh along the way.

Step 4: Lets Add Some Zombies.

With that out of the way go to the asset store and search free zombie character. Import the one from the picture above.

Go to the model folder and click on "z@walk." Under rig change the animation to legacy. Do the same thing for "z@fall_back."

Drag "z@walk" into the scene, rename it "zombie."

Remove the Animator component and add an Animation component.

Expand the "z@walk" in the assets folder and find the walk animation. Drag that into the animation slot of our zombie in the scene. Do the same for "z@fall_back" and drag the fall back animation into the same slot.

Add a nav mesh agent component to our zombie in the scene and change the speed to 1 and it's stopping distance to 3.

Finally, add a capsule collider component and position it so it surrounds the zombies head. This way the only way we can kill a zombie is with a head shot, to make it a little more difficult. Check is trigger on.

Step 5: Add Some Code to Your Zombie.

Now add a new script component to your zombie and call it zombieScript.cs. Copy and paste in this code: (replacing everything that is already there)

using UnityEngine;
using System.Collections;

public class zombieScript : MonoBehaviour {
  //declare the transform of our goal (where the navmesh agent will move towards) and our navmesh agent (in this case our zombie)
  private Transform goal;
  private NavMeshAgent agent;

  // Use this for initialization
  void Start () {
    //create references
    goal = Camera.main.transform;
    agent = GetComponent();
    //set the navmesh agent's desination equal to the main camera's position (our first person character)
    agent.destination = goal.position;
    //start the walking animation
    GetComponent().Play ("walk");

  //for this to work both need colliders, one must have rigid body, and the zombie must have is trigger checked.
  void OnTriggerEnter (Collider col)
    //first disable the zombie's collider so multiple collisions cannot occur
    GetComponent().enabled = false;
    //destroy the bullet
    //stop the zombie from moving forward by setting its destination to it's current position
    agent.destination = gameObject.transform.position;
    //stop the walking animation and play the falling back animation
    GetComponent().Stop ();
    GetComponent().Play ("back_fall");
    //destroy this zombie in six seconds.
    Destroy (gameObject, 6);
    //instantiate a new zombie
    GameObject zombie = Instantiate(Resources.Load("zombie", typeof(GameObject))) as GameObject;

    //set the coordinates for a new vector 3
    float randomX = UnityEngine.Random.Range (-12f,12f);
    float constantY = .01f;
    float randomZ = UnityEngine.Random.Range (-13f,13f);
    //set the zombies position equal to these new coordinates
    zombie.transform.position = new Vector3 (randomX, constantY, randomZ);

    //if the zombie gets positioned less than or equal to 3 scene units away from the camera we won't be able to shoot it
    //so keep repositioning the zombie until it is greater than 3 scene units away. 
    while (Vector3.Distance (zombie.transform.position, Camera.main.transform.position) <= 3) {
      randomX = UnityEngine.Random.Range (-12f,12f);
      randomZ = UnityEngine.Random.Range (-13f,13f);

      zombie.transform.position = new Vector3 (randomX, constantY, randomZ);



Step 6: Almost There!

Create a folder inside your assets folder and call it "Resources"

Drag your zombie into that folder. Now copy and paste that same zombie and add however many you would like anywhere in the scene.

Now we have to create a bullet.

Create a new sphere and scale it down to .01 across the board.

Rename it bullet and drag that into the resources folder as well. You can delete the one in the scene.

Drag in the gun model into the scene. Expand it and find one of its children called n3r-v. This is a smaller model of the gun. Drag it outside of its parent game object because this is the one we are going to use, so delete everything else.

Now re-position and rotate your gun so that it is pointing to the center of the screen and you can see it in play mode. Drag it on top of your camera making it a child.

Right click the gun and create a 3d object, sphere. This will make it a child. Rename it "spawnPoint"

Scale it down to .001 across the board and move it to the very tip of the gun barrel, this is where the bullets are going to spawn from.

Step 7: Add Some Code to Your Camera

Add a new script component to the camera and name is playerScript.cs. Copy and paste in this code:

using UnityEngine;
using System.Collections;

public class playerScript : MonoBehaviour {

//declare GameObjects and create isShooting boolean. private GameObject gun; private GameObject spawnPoint; private bool isShooting;

// Use this for initialization void Start () {

//only needed for IOS Application.targetFrameRate = 60;

//create references to gun and bullet spawnPoint objects gun = gameObject.transform.GetChild (0).gameObject; spawnPoint = gun.transform.GetChild (0).gameObject;

//set isShooting bool to default of false isShooting = false; }

//Shoot function is IEnumerator so we can delay for seconds IEnumerator Shoot() { //set is shooting to true so we can't shoot continuosly isShooting = true; //instantiate the bullet GameObject bullet = Instantiate(Resources.Load("bullet", typeof(GameObject))) as GameObject; //Get the bullet's rigid body component and set its position and rotation equal to that of the spawnPoint Rigidbody rb = bullet.GetComponent(); bullet.transform.rotation = spawnPoint.transform.rotation; bullet.transform.position = spawnPoint.transform.position; //add force to the bullet in the direction of the spawnPoint's forward vector rb.AddForce(spawnPoint.transform.forward * 500f); //play the gun shot sound and gun animation GetComponent().Play (); gun.GetComponent().Play (); //destroy the bullet after 1 second Destroy (bullet, 1); //wait for 1 second and set isShooting to false so we can shoot again yield return new WaitForSeconds (1f); isShooting = false; } // Update is called once per frame void Update () { //declare a new RayCastHit RaycastHit hit; //draw the ray for debuging purposes (will only show up in scene view) Debug.DrawRay(spawnPoint.transform.position, spawnPoint.transform.forward,;

//cast a ray from the spawnpoint in the direction of its forward vector if (Physics.Raycast(spawnPoint.transform.position, spawnPoint.transform.forward, out hit, 100)){

//if the raycast hits any game object where its name contains "zombie" and we aren't already shooting we will start the shooting coroutine if ("zombie")) { if (!isShooting) { StartCoroutine ("Shoot"); }

} } } }

Step 8: Click Play!

Click play and go back to your scene view.

We are casting a ray from the spawn point in order to detect if the gun is pointing at a zombie. So, you will see a green line coming from the tip of the gun. Rotate the spawn point until that line is pointing straight out of the gun barrel. Click the top right of the spawn points transform box to copy the component values. Click play again to exist play mode. Click that same area on the spawn point's transform again and paste the component values. We have to do this because changes don't get saved in play mode.

At this point everything should be working!

If you want to create a laser sight, right click in the asset folder and create a new material, change the albedo and emission to red. Create a new cube and make it a child of the gun. Scale its z to 1000 and everything else to .1.

This should make a long line that you can then drag your red material onto.

Reposition the sight so it is coming straight out of the end of the gun barrel.

Step 9: Transfer the Game to Your Phone!

Plug your phone in via usb to your computer.

For IOS go to build settings, player settings and change resolution to landscape left.

Change the bundle identifier to something like com.YourName.YourAppName

Download xCode if you don't already have it and create a free apple developer account. It will have you create a team and make sure that team is chosen when you are building out. Hit build and run and you should be good to go.

For Android make sure you have usb debugging turned on and in player settings just set default orientation to landscape left. Click build and run and everything should transfer to your phone.

Thanks for looking! Let me know in the comments if you have any questions!

Make Noise Challenge

Participated in the
Make Noise Challenge

Epilog Contest 8

Participated in the
Epilog Contest 8