How to Make Enemies and Influence Zombies. The only guide you need to lead you to FPS success!

The next phase in our Zombie FPS course had us create a preliminary enemy. As in our Spaceship shooter, we’re still in our preliminary phase so we’re going to focus more on workable gameplay than graphics, so the zombie we’re making is going to be a cube.

Actually, let’s make it a little taller and more zombie/enemy like. let’s make it 3 units tall and give it a red texture.

There’s a few more preliminary steps to prepare this Enemy for action, let’s rename it to Enemy, we’ll also remove the box collider and replace it with a character controller.

Finally we’ll make a script called EnemyAI which we’ll place in our enemy.

Finally, make a prefab folder and make the enemy a prefab!

We’ll also do a bit of housekeeping in our scripts folder and create Player and Enemy folders and place the Player and Shoot script in Player, and EnemyAI in Enemy.

Next, we are challenged to write an AI script for the enemy:

The parameters we’re given:

//We need a reference to the character controller.

In Update()

//Check if grounded
// Calculate direction: destination (player)- source(transform)
// Calculate velocity: direction * speed
// if not grounded, subtract gravity
// Using the controller method, move to player which is move to velocity.

So looking at this, we’ll need the following variables:

characterController, or maybe just controller.
direction, velocity, speed, and gravity and a holder for the player so let’s set that up:

We’ll have to assign the player and character controller as well as speed and gravity, let’s do that in Start().

Whenever you’re assigning a holder, it’s always best-practice to create a null-check for it, now in Update()

//Check if grounded:

// Calculate direction: destination (player)- source(transform)

// Calculate velocity: direction * speed

// if not grounded, subtract gravity

// Using the controller method, move to player which is move to velocity.

And for reference, here’s the entire script at this moment:

So let’s see it in action!

Wow that enemy is coming up to us REALLY fast!!!

Apparently, the reason it’s happening is when we calculate the direction, we’re also calculating the entire length from the enemy to the player as well, Normalize() is a function that can help us cut it down to just 1 unit so the enemy travels a little more slowly by moving 1 unit at a time or one unit per second instead of the entire length of let’s say 7 units in that second.

Now let’s try it, I’ll also put the enemy a little further away:

MUCH better!

For snits and giggles, I added some ‘arms’ to our enemy ‘zombie’ so I could tell what direction they were facing when moving.

Now let’s see how our zombie friend moves:

Well, they’re heading towards us, but they’re not rotating…

We want it to look where it’s going, so we need rotation. There’s a method called Quaternion.LookRotation which should be right up our alley!

So we change our current rotation to the Quaternion.LookRotation that is based on the direction the zombie is going. Simple enough!

I updated the speed to around 6 to show a potential problem:

Our zombie friend is tilting and about to fall over on us. We can fix this by zeroing out the y-direction every frame.

Wonderful! Our enemy is now staying upright! I’ll change the speed back down to a more manageable level, but I think we have our AI worked out! Next time we’ll go into damaging the enemy's health!

For reference, here’s the current complete code for the enemy.

cartoonist, game artist, and wanabe gamedev.