Jump to content
  • Advertisement
  • entries
    44
  • comments
    19
  • views
    2421

100 Days of VR: Day 5 Survival Shooter Tutorial I

Josh Chang

637 views

Alright, we’re back at it again, with day 5 of working with Unity. We just finished the Unity Space Shooter tutorial from Day 2–4 and now today we’re going on to look at the next set of tutorials: the Survival Shooter tutorial!

Building up on what we already learned in our toolkit, we’re going to learn more about:

  • Setting up the environments
  • Using Unity’s built in AI system

Install

Just like the previous tutorial, download the resource assets through the Unity Store or through the Learn tab when you create a new project.

Once we have the package, just like what we did before, create a new project and import the Survival Shooter project so we can have our initial setup.

Environment Setup

The first thing to do is create a scene by hitting ctrl + S.

I called my scene main, but it could be anything you want.

After that, go to the prefab folder and drag the environment prefab object to the game hierarchy and you’ll see something like this:

 
0*MU-G6IlC3Fb3HdBL.png

If you actually expand the Environment prefab you’ll see that it’s just a container game object that contains multiple child game objects like walls, chairs, and other game objects.

The next step is to create a floor for our player to walk on, similar to the previous tutorial, we create a Quad and set it the floor like so:

 
0*Ri2A4vIU5Txgz7bj.png

My settings for it are:

  • Position: 0, 0, 0
  • Rotation: 90, 0, 0
  • Scale: 70, 70, 1

Disable the Mesh Renderer

The last part is to go to the Mesh Renderer component of quad and disable it.

We just need the floor to be there for its collider to detect when our mouse is clicking down later on. We don’t need to be render the floor.

Set the Layout to Floor

Another important thing to do is to go to the inspector for our Quad and under Layout select Floor.

We can see this used later on, but its main purpose is for us to be able to optimize our cod searching when for the floor later on.

Add Background music

The last thing we did in this video is create an empty Music GameObject and attach an AudioSource component to it and set Background Music as our AudioClip.

Normally we would set our music to Play On Awake and Loop, but that would be annoying in the beginning, we just disabled it for now.

Player Character

Great! So now we have our environment setup, the next thing we did was create the Player object. The tutorial has all of the models located inside the Model folder. Drag the Player model to the hierarchy.

You’ll see something like this:

 

Cool! We have a character. Make sure to set the Tag for our character to be Player.

Next up, we create something called an Animator Controller for our character, by right clicking on the project pane creating an Animator Controller

An Animation Controller is described as a finite state machine. A state can be something like walking or idle. When you’re in one state, you can only go into a different state if:

  • There’s a transition in your current state that allows you to move to another state.
  • You meet the criteria set in your transition.

We’ll understand more as we move on in the video.

But first, what are we going to animate?

Each character models provided by Unity has their own animations provided!

For example, if you click on the Character model for Player in the project pane and look in the inspector, you’ll see what animation clips are attached to the model:

 
0*VH-WDgMFBN064eQn.png

As you can see we have a Move, Idle, and Death animation.

Creating the Animator Controller

They first thing to do is to go to the Animation folder, right click, and create a new Animator Controller.

We call it PlayerAC. After we created it, we double clicked it to open it up.

 
0*oc4DQHaz54nNyFQF.png

This will open up the Animator pane for us to use.

We want to create a state for each of the animation clip we have for our character.

We can easily add that in by dragging the animation clip from the character model into the Animator. You’ll see something like this:

 

Creating Transitions

Now notice that we have an arrow from Entry to Idle. Entry indicates our starting state. If your Idle state isn’t orange, that means it’s not the default state that the animation will enter. Right click Idle and make it the default state and you should see something like above.

Creating Parameters to change between states

Noticed the circle parameter in the above image?

In the Parameters tab, we can create conditions that must be made to transition from one state to the next. We created 2 parameters:

IsWalking, a Boolean, a Boolean is as you expect, either if something is true or false.

Die, a Trigger, a Trigger is similar to a Boolean, but the moment it becomes true, it’s immediately changed into false.

Creating the First Transition with our Parameters

Currently, when we start the game, our character would only be idle.

What other states can a player transition to from idle? Move! (Technically they can die too, but we’ll do something else with that)

Click Idle and create a transition and select Move as the selection target.

Next we click on the transition arrow that we created. Look in the inspector under the Conditions tab, select IsWalking and select true for it.

 
0*1_Av5rEPGTa8NlqY.png

Next do the same thing from Move and select Idle and set the ConditionsIsWalking to be false, which means if we’re walking and decide to stop, we go back to playing the Idle animation.

Once you’re done, you’ll see something like this:

 
0*3K6GDxO9npztIuQh.png

Using the Any State

Now what about when the player dies?

We could create a transition from both Idle and Move to death, but, because we can die at any state, we use the Any State state.

As you can imagine, Any State allows us to create a transition no matter what state we’re currently in.

Create a transition from Any State to Death and set the Die as the parameter

 

Adding RigidBody to the Player Container

Next we add a RigidBody component to our Player GameObject. We set the Drag and Angle to Infinity¸ I’m not really sure what this does, but according to the documentation, it’s like friction slowing players down.

We also want to set Constraints to freeze positions to prevent them from moving:

  • Freeze Y position — prevent player from going up and down (like jumping)
  • Freeze X and Z rotation — prevent player from rotating in a weird angle

After adding the RigidBody, we also add a Capsule Collider and an Audio Source with the Player Hurt as the Audio Clip

Player Movement script

The next thing to do is that we attach the provided PlayerMovement Script to our Player. The code has been well commented, so I won’t delve too much into what they do.

using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
    public float speed = 6f;            // The speed that the player will move at.
    Vector3 movement;                   // The vector to store the direction of the player's movement.
    Animator anim;                      // Reference to the animator component.
    Rigidbody playerRigidbody;          // Reference to the player's rigidbody.
    int floorMask;                      // A layer mask so that a ray can be cast just at gameobjects on the floor layer.
    float camRayLength = 100f;          // The length of the ray from the camera into the scene.
    void Awake ()
    {
        // Create a layer mask for the floor layer.
        floorMask = LayerMask.GetMask ("Floor");
        // Set up references.
        anim = GetComponent <Animator> ();
        playerRigidbody = GetComponent <Rigidbody> ();
    }

    void FixedUpdate ()
    {
        // Store the input axes.
        float h = Input.GetAxisRaw ("Horizontal");
        float v = Input.GetAxisRaw ("Vertical");
        // Move the player around the scene.
        Move (h, v);
        // Turn the player to face the mouse cursor.
        Turning ();
        // Animate the player.
        Animating (h, v);
    }
    void Move (float h, float v)
    {
        // Set the movement vector based on the axis input.
        movement.Set (h, 0f, v);
        
        // Normalise the movement vector and make it proportional to the speed per second.
        movement = movement.normalized * speed * Time.deltaTime;
        // Move the player to it's current position plus the movement.
        playerRigidbody.MovePosition (transform.position + movement);
    }
    void Turning ()
    {
        // Create a ray from the mouse cursor on screen in the direction of the camera.
        Ray camRay = Camera.main.ScreenPointToRay (Input.mousePosition);
        // Create a RaycastHit variable to store information about what was hit by the ray.
        RaycastHit floorHit;
        // Perform the raycast and if it hits something on the floor layer...
        if(Physics.Raycast (camRay, out floorHit, camRayLength, floorMask))
        {
            // Create a vector from the player to the point on the floor the raycast from the mouse hit.
            Vector3 playerToMouse = floorHit.point - transform.position;
            // Ensure the vector is entirely along the floor plane.
            playerToMouse.y = 0f;
            // Create a quaternion (rotation) based on looking down the vector from the player to the mouse.
            Quaternion newRotation = Quaternion.LookRotation (playerToMouse);
            // Set the player's rotation to this new rotation.
            playerRigidbody.MoveRotation (newRotation);
        }
    }
    void Animating (float h, float v)
    {
        // Create a boolean that is true if either of the input axes is non-zero.
        bool walking = h != 0f || v != 0f;
        // Tell the animator whether or not the player is walking.
        anim.SetBool ("IsWalking", walking);
    }
}

However some key points I want to point out that I learned from the video from this was:

Awake()

Similar to Start(), Awake() is called before the game starts, specifically, you can use it to initialize variables that the GameObject that the script attached to has, but not with other game objects.

Raycast

Part of Unity’s built in Physics system, a Raycast is a straight line that shoots forward and if you hit the target that you specified for it, the function call will return true.

You have to give the Raycast a RaycastHit reference to store the information of the object that was hit. You can think of this as another way of having a collider. In this case, we use our mouse.

So let’s break down our parameters:

Physics.Raycast (camRay, out floorHit, camRayLength, floorMask)

camRay: As described by the comments: “Create a ray from the mouse cursor on screen in the direction of the camera.”

floorHit: A variable that stores the information of the object that we hit. Think of the other GameObject when we have a collision with a collider.

camRayLength: How far the raycast will go from the starting location. In this case: from the camera to the location that the player’s mouse is pointing to in the game.

floorMask: An int representation of the layer that we only want to look for collisions. We use these floormask to help us collide with only the object we want, helping us save precious processing power.

Normalized Movement

In part of the movement code, we normalized our value:

movement = movement.normalized * speed * Time.deltaTime;

According to the video, if we go horizontal or vertical, we’ll move 1 unit, however, if we were to move diagonally, we would move 1.4 unit or more, allowing the players to exploit the game. Normalizing prevents the diagonal 1.4 unit movement.

Quarternion

We learned this before, but Quarternion is the specific way that Unity works with Rotation. If you want to do anything with Rotation, we’ll need the Quarternion class.

Sidenotes:

After this point, I found that I could move my character, but it wouldn’t rotate to my mouse. If this is happening to you, it’s probably, because you forgot to set your floor to have the layout Floor.

 

Camera Setup

Great, so now we have our player and we can move him around…. Except in our current game state, the game looks pretty 2Dish. Now the tutorial touches on this topic.

Setting up the camera

Go to our camera GameObject and make these changes:

  • Set camera position to: 1, 15, -22
  • Rotation to: 30, 0, 0
  • Projection: Orthagaonic from Perspective.
  1. Perspective has depth, orthagonic doesn’t
  • Size: 4.5
  • Background to black

You should have something like this, but feel to play around with the settings.

 

Adding the Camera Script

Now that we setup our camera, the next thing to do is to add the provided Camera Script from the script folder:

using UnityEngine;
using System.Collections;
public class CameraFollow : MonoBehaviour
{
    public Transform target;            // The position that that camera will be following.
    public float smoothing = 5f;        // The speed with which the camera will be following.
    Vector3 offset;                     // The initial offset from the target.
    void Start ()
    {
        // Calculate the initial offset.
        offset = transform.position - target.position;
    }
    void FixedUpdate ()
    {
        // Create a postion the camera is aiming for based on the offset from the target.
        Vector3 targetCamPos = target.position + offset;
        // Smoothly interpolate between the camera's current position and it's target position.
        transform.position = Vector3.Lerp (transform.position, targetCamPos, smoothing * Time.deltaTime);
    }
}

Looking at the code, everything has already been provided to us nicely commented so I’ll leave this part as is.

Creating Enemy #1

Now that we have a character that we can control on the map, the next thing we have to add is the enemy that appears on the screen.

The first thing to do is drag the Zombunny character model into the scene.

The enemy also has their own animation clip.

Some things from the video that we need to do to our model…

Attach the particle effect prefab to our zombie that plays when it gets hit

 
0*ENPLy6RO-ysqyZaX.png

Set the Zombunny hurt sound to our model make sure it doesn’t Play On Awake.

Create a capsule collider for our enemy:

 

Set the Layer for our Zombie to be Shootable, if it doesn’t exist, create one.

 

Finally attach a new Nav Mesh Agent to our GameObject.

 

A Nav Mash Agent is an AI that Unity provides for us that will allow our zombie to intelligently chase the player while avoiding obstacles.

Make sure that your setting is the same as above, specifically the radius and height

Creating a Nav Mesh

What makes the AI efficient is that it doesn’t have to do the calculations to figure out what it can and can’t walk on.

We do this by creating a Nav Mesh that tells the AI if the object they’re on is something they can step on.

Reference the image below for an idea of what I’m talking about. The blue is the space that the enemies can navigate:

 

You can create the Nav Mesh by going to Unity > Window > Navigation

In the Navigation pane next to your Inspector, select Bake.

There are 4 values that you need to know:

  • Radius — How close the AI’s can move to a wall
  • Height — How high the AI’s can something be before the player can’t pass it
  • Step height — How tall the AI’s go before the environment blocks the AI
  • Max slope — How high of a slope an object can be before it becomes inaccessible to the player

Here’s the value of what you should have:

 
0*iTfI9I1B2XQh2Gz8.png

After you’re done, press Bake to create your Nav Mesh.

What’s important to mention is that if you want to include game objects to be baked, you have to make sure that they’re set to be static inside the inspector.

An easy way of doing this is to put everything in a parent container and make the parent static. This will make all the children static too.

Creating the Enemy AC

Now that we have an AI, we don’t have to write any complex AI scripts to figure out how to navigate.

We can just use the Nav Mesh Agent component. However, before we do that we have to create the animation for our enemy.

Similar to our Player model, we have to create an Animator Controller for our Zombunny.

First we go to the animation folder, right click, and make a new Animator Controller, call it EnemyAC.

Open EnemyAC and then drag and drop the animation clips from the Zombunny model into the controller.

We need to make 2 triggers:

  • PlayerDead
  • Dead

We have 3 animation clips:

  • Move
  • Idle
  • Death

Move is our main transition state.

The only time we want our zombie to be idle is when they win and our player is dead, so create a transaction from Move to Idle that’s caused by the PlayerDead trigger.

Similar to when the player dies, if the enemy dies, it doesn’t matter which state, we play the death animation. We create a transaction from Any State to Death that’s caused by the Dead trigger.

When we’re done, we should have something like this:

 
0*_puIaLfQlNU_3RQV.png

Enemy Movement Script

Nav Mesh Agent made? Check. Animation Created? Check. Let’s use everything!

In the Script folder, we’ll find an already made EnemyMovement script. Attach it to the Enemy.

using UnityEngine;
using System.Collections;
public class EnemyMovement : MonoBehaviour
{
Transform player;
//PlayerHealth playerHealth;
//EnemyHealth enemyHealth;
UnityEngine.AI.NavMeshAgent nav;
void Awake ()
{
player = GameObject.FindGameObjectWithTag ("Player").transform;
//playerHealth = player.GetComponent ();
//enemyHealth = GetComponent ();
nav = GetComponent ();
}
void Update ()
{
//if(enemyHealth.currentHealth > 0 && playerHealth.currentHealth > 0)
//{
nav.SetDestination (player.position);
//}
//else
//{
// nav.enabled = false;
//}
}
}

Note: At this point, it’s important to note that we don’t use everything in the code right now. Either copy the code from the video or manually comment out the lines.

The code itself is pretty straightforward. We instantiate our Player and Nav Agent Components and then make our Nav agent go to our player’s location in Update().

nav.SetDestination (player.position);

After we’re done with that, if we go back to the game and play, the enemy will start chasing us.

 
0*BSE8eyJgZLkshuuc.png

Conclusion

We made a lot of progress today, we setup the environment, added the player and enemy in, and then created a Nav Mesh Agent to help our enemy chase our player around.

I’ll try to finish the rest of the tutorial and finally move on to creating a simple game feature to display some level of mastery next!

Until then, I’ll see you all in Day 6!

See the original Day 5 here.

See the 100 Days of Unity VR development



0 Comments


Recommended Comments

There are no comments to display.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Advertisement
  • Advertisement
  • Blog Entries

  • Similar Content

    • By Jamesgz
      Hey my dudes,
      Me and 4 friends are third year compsci students. Three of us are pretty good at drawing. We are hoping to make a 2d roguelite game with unity during the next few months. We are still brainstorming. At the moment, my idea is to create a card roguelite game:
      First, you would need to choose 2 heroes to enter the dungeon with the goal of finding a treasure. The treasure found gives you extra bonus in later runs. You can choose between mage, gunner, rogue, paladin, warrior and fighter. Each hero has their own unique cards. And there are common cards that every heroes can get(like hearthstone).
      The progression system would be like slay the spire’s. You can choose your own path, but every paths leads to the boss. It would use procedural generation. After defeating an enemy, you get to choose a new card out of the three options. There would be shops, random events, elite enemies, etc
      The combat system is where i need some suggestions on. There would be two piles of deck. One for each hero. I can think of two good combat systems:
      1. Before every enemy encounters, you can choose what cards to use from your deck. Cards not used would not get discarded. Cards are drawn from the deck only if they break or due to special card’s effect. Every card have a durability number. Ones the durability reach zero, the card would break and can no longer be used. Events/enemies can modify the durability of the cards.
      2. Card not used this turn would get discarded. Once the deck is empty, the discard pile gets shuffled and copied to the deck. Card/item effects can increase the number of cards you draw.
      How can I make the game more interesting? Any suggestions would be appreciated.
    • By horror_man
      Hello, I'm currently searching for a talented and passionate programmer to create a small but great horror game that would take around 3 months to be done.
       
      About the game: The game would be a sci-fi/post-apocalyptic survival horror 3D game with FPS (First person shooter) mechanics and an original setting and story based in a book (which I'm writing) scene, where a group of prisoners are left behind in an abandoned underground facility. It would play similar to Dead Space combined with Penumbra and SCP: Secret Laboratory, with the option of playing solo or multiplayer.
       
      Engine that'd be used to create the game: Unity
       
      About me: I'm a music composer with 4 years of experience and I'm fairly new in this game development world, and I'm currently leading the team that'd be creating this beautiful and horrifying game. I decided that making the book which I'm writing into a game would be really cool, and I got more motivated about doing so some time ago when I got a bunch of expensive Unity assets for a very low price. However, I researched about how to do things right in game development so I reduced the scope of it as much as I could so that's why this game is really based in a scene of the book and not the entire thing (and also that's why it would take 3 months). Also I'm currently learning how to use Unity and how to model things with Blender.
       
      Our team right now consists of: Me (Game Designer, Creator, Music Composer, Writer), 3 3D Modelers, 1 Sound Effect Designer, 1 Concept Artist and 1 Programmer.
       
      Who am I looking for:
      - A programmer that's experienced in C# and with Unity.
       
      Right now the game is very early in its development (GDD is completed and all 3D Items, Music and Sound Effects are completed).
       
      If you are interested in joining, contributing or have questions about the project then let's talk. You can message me in Discord: world_creator#9524
    • By kcirkl
      Hello, 
      So, I'm aware this may be a broad question with a vast variety in the anwser. However, I am a game design student that works professionally for a large engineering company conducting software configuration. Naturally, I'm curious about the path ahead and I'm desperately gathering information on the overall process of developement with Unity. Are there professional resources available that can outline the processes and functions of the engine, and what can be used to interact with it? I'm looking for options other than the official documentation. I have already jumped into that. Thanks!
    • By tspartant
      Hey everyone! My name is Ryan and I am the founder of Visualistic Studios, LLC. 
      I'm looking for experienced developers interested in short term and long term contracting. For the past 3 years I've been working in game development contracting, and the past year I've been working full time from home. Since then, I've received more and more contracts and I'm now at the point that I have too many for myself to handle. I have at least another full time job's worth of programming offers, and around 30-80 hours a month for 3D modeling/animation. I also am in need of a UI artist, so if you're talented please contact me! I have contracts using Unity as well as Unreal Engine 4, so if you can program in either please contact me. 
      If you are interested in working on these contracts, please send me links to your work and you hourly rate. (Most contracts range be between 18-25$/h, but please provide your normal hourly rate)
      You can get ahold of me through email - "ryan.hobbs@visualisticstudios.com", or Discord "TSpartanT#4670"
       
      Thank you everyone for reading, hope to hear from you soon!
    • By MiTi
      Dear everyone, this is my newest game, please check out and give me feedback. Thanks for your consideration.

      Overview: Cross n Puzz is a creative and addicting word puzzle game. It not only challenges your brain but also improve memory and other types of cognitive function.

      For IOS: https://itunes.apple.com/app/crossword-puzzle-image/id1435575074

      For Android: https://play.google.com/store/apps/details?id=com.caag.crosswordnpuzzle

      Game trailer: https://www.youtube.com/watch?v=stNuktpJH44&feature=youtu.be
      Crossword Puzzle Image Trailer Official.mp4  
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!