Day 27 of 100 Days of VR: Adding New Bandit Enemy

posted in From Zero To VR
Published October 16, 2017
Advertisement

Welcome to Day 27!

Right now, we have a relatively complete game and in my mental roadmap, we only have a couple more things to do before we start exploring how to use VR and then implementing that back into this game.

There will be a lot of fun times ahead!

Our goal is to create a new enemy. Specifically, for practice, I want to create:

  1. A lower health, but faster unit
  2. A higher health, but slower unit

With these new enemies, we’ll have a more diverse and interesting experience in our game!

Today, we’re going to focus on creating our speedy unit.

Step 1: Acquire new assets

The first thing we need to do is go to our favorite place in the world! The Unity Asset Store!

We’re going to look an asset to be used as our enemy. When looking for new assets, the most important thing for us is to find something that’s mecanimready.

If you’re not aware of the glory that is the mecanim system, you can visit Day 11 where we first used it.

The basic summary is that all Unity models can have rigged body structure that can share animations from other models with similar body structures without doing any extra work on our end.

Step 1.1: Get bandit asset

Browsing around the asset store for an enemy to use and I found a nice bandit to use for the speedy enemy!

It’s called Basic Bandit:

 
0*_x2JsJSotyJM5ewN.png

Download and import the bandit into our game. It’ll be in Assets > BasicBandit.

Step 2: Setup BasicBandit

Now that we have our assets the next thing we need to do is to setup up our BasicBandit asset to use our existing animation and scripts!

This work will be the same as what we have done with the knight model, except we don’t have to code anything this time!

Step 2.0: Set Wave 1 SpawnManager to Spawn -1 Enemies

Not necessary, but for the ease of testing our new enemy. If we set Wave 1 of our SpawnManager, to spawn -1 enemies, we won’t create any new enemies and the wave won’t progress, allowing us to experiment around with our enemies.

Another option is to comment out the instantiation code in SpawnManagercode to not create any new enemies.

 
0*IfMtBGHvGhnGrA-4.png

Step 2.1: Attach the Knight Animatior Controller

The great thing about Unity’s mecanim system is that we can re-use existing animator controllers for models that share the same animation.

In this case, because our knight and bandit are both humanoids, we can share our Knight Animator Controller with our bandit.

Now let’s do it!

  1. In Assets > BasicBandit, drag and drop Basic_BanditPrefab into our game.
  2. Select our bandit in the hierarchy and in the Animator component, under Controller, select our Knight Animator Controller to fill in the slot.

You’ll have something like this now:

 
0*MldXUl1WG2e3ab_z.png

Now with this, our bandit will have the same animation rules as our knight (running, attacking, death, and idle)

Step 2.2: Add the Nav Mesh Agent and the 3 scripts: EnemyHealth, EnemyAttack, and EnemyMovement

At this point, we want to re-create everything that’s attached to our Knight and move it to our bandit.

We want to add the following things to our BasicBandit by clicking Add Component in the inspector:

  • Nav Mesh Agent component to be the navigation AI to make the bandit chase after the player
  • EnemyHealth: to receive the damage when the player shoots the enemy
  • EnemyAttack: to detect when the enemy injures the player
  • EnemyMovement: to control the movement logic for the enemy

Step 2.3: Setting up the Scripts and Nav Mesh Agent

Now that we have attached our script, we need to set them up.

Nav Mesh Agent

For our Nav Mesh Agent component, we want to adjust the speed of how fast it moves.

Let’s set the Speed to be 3.25. Our Knight’s speed is 3.

 
0*SLXRhkAMhLxc4Mp7.png

EnemyHealth

For our Enemy Health we want to set:

  • Health: 5
  • Hit Sfx Clips > Size: 4
  • Set the 4 new Audio Clips to be Male_Hurt_01 — Male_Hurt_04
  • Hit Sound Delta: 5
 
0*sdPRdfka9z5RYiW0.png

EnemyMovement

For the EnemyMovement scripts, we want to set:

  • Walking Clips > Size: 4
  • Set the 4 new Audio Clips to be Footstep01 — Footstep04
  • Walking Delay:3
 
0*r10SkeKzZleAq-WS.png

EnemyAttack

We don’t have everything for our EnemyAttack script, but let’s set what we can first.

  • Attack Sfx Clips > Size: 3
  • Set the 3 new Audio Clips to be Punch_01 — Punch_03
  • Leave the Fist Colliders alone for now
 
0*TjkehHUqm7myjPtL.png

Now if we were to play the game, our Basic_Bandit will start chasing after us, but he won’t attack us yet, we haven’t set up our triggers and colliders yet!

Step 2.4: Adding 3 Colliders: Trigger Collider, Mesh Collider, and Fist Colliders

The final thing that we need to do is to add colliders to our bandit that will help us detect when the player is close, when the enemy damages our player, and when they get hit.

To do a re-cap the purpose of what we need to do, we need:

  • A Capsule Collider to be used as a trigger to tell our bandit to enter attack mode if he’s near the player.
  • 2 Box Collider that will be attached to the bandit’s hand to tell when we damage the player.
  • A Mesh Collider to be used for detecting when the player shoots the bandit.

Let’s add them in.

Adding the Capsule Collider

Select Basic_Bandit in the hierarchy and then add the Capsule Collider component.

We’ll make it a trigger, set the Y to be 1, and then expand Radius to be 1.5.

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

 
0*NyoUTz23QCvm-D5m.png

Note: the radius is the outer sphere that you see.

To do a re-cap, whenever our player enters the circle, in our EnemyAttack script, we’ll hit OnTriggerEnter() which is used to tell the bandit that it’s in range to be able to hit the player.

Adding the 2 Box Colliders

Next up, we need to add 2 Box Colliders to our Bandit’s fists.

Select Basic_Bandit > Armature > Hips > Spine > Chest > Shoulder.L > UpperArm > LowerArm > Hand.L

We want to add a Box Collider to Hand.L

In our Transform, we’ll keep position the same, however, let’s change the Size of our Box Collider:

Size (X, Y, Z): 0.1, 0.3, 0.1

Finally, just attach the Fist Collider Script to Hand.L.

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

 
0*QuqtRJcW6WNdA0od.png

Now do the exact same thing to the other hand in Hand.R.

Adding the Mesh Collider

Next up is the Mesh Collider component.

As we learned in Day 20, adding our collider into the parent object will not work, we should put the collider in the location of the mesh itself.

This would serve us 2 purposes:

  1. We can shoot the enemy
  2. The enemy can push us around

In the bandit’s case, we have 2 pieces: the body and the clothes.

 
0*7EyN8bZjQFyG7YVZ.png
 
0*y-fjZNLDdNeiuq_B.png

What you see above is the Mesh Collider in each of the pieces of the mesh of the bandit.

Let’s get started!

In BasicBandit_Body, add a Mesh Collider component, under Mesh add the mesh BasicBandit_Clothes. With this, you’ll have the 1st image above.

Here’s what it should look like:

 
0*j8zQxxzxYDojX0rp.png

Next:

In BasicBandit_Clothes, add a Mesh Collider component, under Mesh add the mesh BasicBandit_Clothes. With this, you’ll have the 2nd image above.

And here’s what it should look like:

 
0*lvaRtpzp3zjoZQ6H.png

At this point, we’re almost there.

We have the colliders to detect when our bandits get hit, however, if we were to try and shoot our enemy, we wouldn’t “hit” him yet.

Step 2.4: Set Bandit’s Layer to be Shootable

As you might recall when we were shooting enemies with Raycasting in PlayerShootingController, we did an optimization to only hit objects that have a layer mask set to Shootable.

Select our bandit in the hierarchy and set our Layer to be Shootable.

 
0*IsEWZKLIW6TvOJsZ.png

Now with these colliders set, we can shoot the bandit and they’ll take damage and be knocked back.

Step 2.4: Attach our Fist Colliders to EnemyAttack

Earlier on, we attached our First Collider script to the bandit’s hands. It’s time to attach both of our hands to our EnemyAttack Script so we can detect if either of our the bandit’s fists makes contact with the player in Attack().

In EnemyAttack set:

  • Left Fist: L
  • Right Fist: R

Step 2.5: Create a prefab of our Bandit

Now that we have everything setup, we’re going to make a prefab of our finished bandit model.

Drag our finished copy of Basic_Bandit in our hierarchy into Assets > Prefabs.

Let’s also rename our prefab to be just called Bandit.

 
0*VGDk5JGhhphaamtr.png

Conclusion

Now with all these changes added in, we will have a fully functional Bandit enemy!

I do want to mention that the game won’t function perfectly, for example, if we were to get killed by the Bandit, he’ll continue to attack us.

The reason is that our Bandit isn’t in the Enemy Container game object, which means he won’t be disabled.

In fact, our current Bandit isn’t parented by anything at all! That’s why he doesn’t stop after the player character dies.

We can fix that by removing the bandit and adding him as one of the spawns for our SpawnManager, however before we do that, I want to create one more enemy to use.

Tomorrow we’re going to create our last and final enemy. Until then!

Source: Day 27

Visit the 100 Days of Unity VR Development main page.

Visit our Homepage

0 likes 2 comments

Comments

Scouting Ninja

Mesh colliders is considered bad practice. The obvious reason is performance, the collision mesh would have to update each of it's vertices at run time, so you have 2 animated. The huge amount of polygons and the fact that the mesh can change shape while colliding is wasting a lot of performance.

Instead you should use capsules, spheres and boxes to build a full collision over the game character, parent these against the bones linked to that part. The same way you added the box colliders to the hands in your example above.

Not only doesn't the mesh deform, it also is much lower polygons than your character mesh, giving you a huge performance bonus.

The other advantages: Easy to find the hit points, because if the head hit box is hit it means the character was shot in the head without these collision boxes you would need vertex weights and complex hit calculations to find out if the head has been hit. Having these colliders also makes it easy to add ragdolls and some engines use it for quick shadows.

This is a Unreal example, wasn't able to find a example in Unity that wasn't a animated gif:

UnrealExample.jpg.de6f2986e8ef1f8851cd49f58a37b7a5.jpg

Unity also supports compound collisions. So you add a empty the the character call it something like "ChestCompound" add the collisions onto that empty to create the complex chest. Now when ever any of the collisions on that empty is hit it would trigger the script attached to the empty as if the collisions was one.

 

For your game now, this isn't important. When you reach the VR stage all optimizations like this will be extremely important so it is something to think about.

October 16, 2017 08:15 PM
Josh Chang

Thanks for the very awesome advice as always Scouting Ninja! I knew Mesh Colliders were bad, but I've never thought of making something similar to it by using individual colliders. Genius!

I'll definitely remember this for the future and if performance becomes an issue.

October 17, 2017 04:49 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Advertisement