Welcome back to day 28!
Yesterday, we started our next task on creating multiple new types of enemies and made a new bandit enemy.
Today, we’re going to create our last enemy, a slower enemy with more health that won’t get pushed back as far.
Today is going to be very similar to yesterday, however we’re going to try and create a new animator controller
for our enemy. We’ve seen this before in the Survival Shooter, which I once again blissfully ignored, however we’re re-visiting this topic today.
Let’s get started!
Step 1: Acquire New Asset
Let’s return to our favorite place in the world! The candy store Unity Asset Store!
Just like yesterday, we’re going to look for an asset that’s mecanim
ready.
If you’re not aware of the glory that is the mecanim
system, you can visit Day 11 where we first used it.
Step 1.1: Get Zombie Asset
I was browsing around the asset store for another enemy to use and found a nice barbarian mage to use for our tank enemy!
It’s called Zombie01:
Download and import the barbarian into our game. It’ll be in Assets
> Zombie_0_1
.
Step 2: Setup the Zombie
Yesterday, we created our Bandit
enemy that we re-use our existing Knight Animator Controller
, however for our Zombie
, I want him (it?) to have different move set and animations.
Today, we’re going to do things differently!
Step 2.0: Set Wave 1 SpawnManager to Spawn -1 Enemies
If you have set our Wave 1 to spawn -1 enemies already, then you don’t have to do anything.
However, if not, go to our SpawnManager
and make this change:
Step 2.1: Creating an Animator Override Controller
To achieve the goal of creating an enemy with new animations (but the same states), we’re going to use the Animator Override Controller.
An Animator Override Controller allows us to give it an Animator Controller for us to override and put our own animation clips in. This is very handy for us if we want to create an enemy that has the same states from another Animator Controller, but you want to use different animations for each state.
Let’s first create the animator.
- Go to Assets > Animator and right click and create a new Animator Override Controller. Let’s call it Zombie Animator Controller.
- Set Knight Animator Controller to be our Controller in our Zombie Animator Controller.
Now you’ll see something like this:
See how we have the same 4 states from our Knight Animator Controller?
With this, we can add our clips in, but which clips?
For this, let’s just re-use the existing ones that came along with the Knight Barbarian.
In Assets > Zombie_0_1 > Animations, we’ll find Zombie_0_1, if we expand the model, we’ll see these animation clips!
As you can see, we have 8 animation clips attached:
attack0
attack1
death
idle0
idle1
run
skill0
wound
If you want to see what each of the animation does, click on the model and you’ll see the clips that are attached and what they each look like:
Unfortunately, because these animations share very similar names, I’m going to have to rename them.
The 4 we’ll need are attack01
, death
, idle0
, and run
. Click on each of them and hit Ctrl + D to duplicate them.
Rename each of them to be ZombieAttack
, ZombieDeath
, ZombieIdle
, and ZombieRun
.
Move these into our Animation folder.
Here’s what we have:
Back to our Zombie Animator Controller, let’s add our clips in and we should have this:
Step 2.2: Attaching the Animator Controller
Now that we have created our Animator controller, let’s create our zombie to use it!
- In Assets > Zombie_0_1 > Animations, drag the Zombie_0_1 model into our game’s hierarchy.
- Add a new Animator component and inside for the Animator Controller, add our Zombie Animator Controller.
Here’s what we should have now:
Note: The Transform
position could be anything. I moved it closer to the player, but in the end, it’s not going to matter, because we’re going to spawn it in our present locations.
Step 2.3: Attaching the Nav Mesh Agent and the 3 scripts: EnemyHealth, EnemyAttack, and EnemyMovement
At this point, everything that we’re going to do is going to be the exact same as the day before.
Select the Barbarian
game object and add a Nav Mesh Agent Component, EnemyHealth
, EnemyAttack
, and EnemyMovement
scripts to it.
Step 2.4: 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 2. Our Knight
’s speed
is 3
and our Bandit’s speed
is 3.25
,
EnemyHealth
For our Enemy Health, we want to set:
Health:
15 Hit Sfx Clips
> Size
: 4
- Set the 4 new
Audio Clips
to be Male_Hurt_01
– Male_Hurt_04
Hit Sound Delta:
5
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
: 7
Knock Back Force
: 9
EnemyAttack
We’re going to do some re-work with our EnemyAttack
script, technically speaking, we should use sound effects that are not punching sounds, however, because we’re only practicing, let’s just use the same sound effects we have been using.
Attack Sfx
Clips
> Size
: 3 - Set the 3 new
Audio Clips
to be Punch_01
– Punch_03
- Leave the Fist Colliders alone for now
Now if we were to play the game, our Zombie
will start chasing after us, but he won’t attack us yet, we haven’t set up our triggers and colliders yet!
Step 2.5: Adding 3 Colliders: Trigger Collider, Mesh Collider, and Fist Colliders
At this point, we’ll be doing nearly the exact same thing as we done yesterday.
We’re going to add:
- A
Capsule Collider
to be used as a trigger to tell our zombie to enter attack mode if he’s near the player. - 2
Box Colliders
that will be attached to the zombie’s weapon to tell when we damage the player. - A
Mesh Collider
to be used for detecting when the player shoots the zombie.
Adding the Capsule Collider
Select Zombie
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:
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 attach colliders to our weapon.
The process won’t be too different compared to working with fists.
In Zombie > Bip001 > Bip001 Pelvis > Bip001 Spine > Bip001 Spine1 > Bip001 Neck Bip001 L Clavicle > Bip001 L UpperArm > Bip001 L Forearm > Bip001 L Hand > Zombie_0_1_002
We want to attach a box collider. We’re just going to make it as big as our weapon.
We need to make some changes with the collider. Specifically, the Z
value for Center
and Size
.
- Set the
Z
value for Center
to be 0.6
- Set the
Z
value for Size
to be 0.2
The reason why we’re doing this is because we don’t want our weapon to block our gun raycasting when we try to shoot the enemy.
Next, we’ll attach our FistCollider
script to our game object.
At this point, we really should call it a weapon collider, but we’ll keep it the same for simplicity.
When we’re done, we should have something like this:
We’ll do the exact same thing for the right weapon as well.
Adding the Mesh Collider
Next up is our Mesh Collider
component.
The same as yesterday, the purpose of the Mesh Collider
is for 2 reasons, it allows us to:
- shoot the enemy
- get pushed by the enemy
For the zombie, this is easy.
All we need to do is add a Mesh Collider component to Zombie
> Zombie_0_1
.
And for the Mesh, attach Zombie_0_1
.
When you’re done, you’ll have something like this:
We’re almost there, we still need to make our game object shootable so we can hit him.
Step 2.6: Set Zombie Layer to be Shootable
Straightforward, just like our Bandit
, we did the day before, we want to go to our Zombie
and change his layer
to be Shootable.
Step 2.7: Attach the Fist Colliders to EnemyAttack
We attached our First Collider script
to the Zombie’s weapons. It’s time to attach both of them to our EnemyAttack Script
so we can detect when the weapon makes contact with the player in Attack()
.
In EnemyAttack
, set:
Left Fist
: Zombie_0_1_002
Right Fist
: Zombie_0_1_1
With this, we can take damage now.
Except for two problems:
- If we don’t move and let the enemy attack us, he just stops attacking us at one point!
- We don’t take damage when our enemy attacks!
Step 2.7: Allowing Enemies to Continuously Attack Us
Fixing the enemy not attacking problem turned out to be straightforward.
If we were to look at the Animator
of our zombie when he attacks us, you’ll notice something interesting.
The zombie is in the right state attack state, but he only attacks us once.
One possible area to look at next is the animation clip: ZombieAttack.
Looking at it, the problem becomes apparent. Our Loop Time
is not checked, which means that our animation won’t loop!
Check it and we’ll solve our first problem.
Step 2.8: Creating an Event in our Animation to Call Attack()
The next problem is that our player character doesn’t seem to notice when they get attacked.
If we were to do some print debugging, if we were to add a print
statement inside our EnemyAttack
script at Attack()
, we’ll notice that we never call Attack()
!
As you might recall, we call Attack()
by setting an event in our animation! Our Bandit
was using the same knight attack animation so we never had to run into the problem, however, our Zombie
uses a new animation!
Let’s fix this:
- Select our
Zombie
game object - In the
Animation Tab
(Window > Animation), select our ZombieAttack
clip. - Experiment around with what’s a good frame to add our event, but I chose
frame 21
- After creating our event, set the function to run to be
Attack()
When we’re done, this is what we’ll have:
With this added in, the Zombie
can now damage us!
Step 3: Create a prefab
Now that we finished our Zombie
enemy, the last thing we need to do is to add it to our Prefabs folder for our SpawnManager
in the future!
We can just call our new prefab Zombie
.
Conclusion
There we go! Now we have 2 more enemies that we can spawn in the game!
Here’s what we have now:
With all our new enemies, the next thing to work on is setting our SpawnManager
to create new waves of our enemy.
We’ll set that up next time! Until then!
Day 27 | 100 Days of VR | Day 29
Home
CodeProject
The post Day 28 of 100 Days of VR: Adding A New Tank Enemy appeared first on Coding Chronicles.