Unity Beginner to Hero Part 14: Enemy Units!

In a previous lesson, we added some functionality to allow objects to be damaged by the rockets we fired. However, the objects we were shooting at were static boxes; not the most exciting foes out there. In this tutorial we will add in an enemy that will follow the player around the level.

Let’s start off by creating another capsule in our scene. Name it “Enemy”, and add a CharacterController component to it. Like we did with our Player earlier, create a Box and parent it to the new Enemy to act as it’s nose. (Since our Enemy will turn to chase the player, it will be important to know which direction he’s facing.) Finally, make sure you delete the Collider components off the Capsule and the Box to ensure our Enemy does not collide with himself. Finally, let’s do something new before we move on to giving our Enemy some logic.

Over in the project panel, right click and select Create->Material. A new material will appear among your assets, indicated by a little blue sphere icon next to it. Name it “Enemy”. Materials are used to define how objects in the game world are rendered. Since we haven’t created any materials before, all the objects in our world use the default Unity material, which is white. Materials define all sorts of behaviour, such as transparency, reflection, color, texture, luminosity—the list goes on. For now, we’ll simply modify this materials color to better display the enemy.

Click on the material. Under Main Maps you’ll see a white color swatch next to Albedo. Select it and choose a color (I picked a saturated red). Once you’re done this, drag the material from the project view onto the capsule and box objects that make up your enemy to turn them red.


Let’s move on to some scripting. Create a new C# script and name it “EnemyMovement”. The job of this script will be to rotate the Enemy towards the player and move in her direction. We can define some public fields with that in mind.

public float speed = 2.0f;
public float turnSpeed = 180.0f;

private CharacterController controller;
private Transform player;

We’ve also added a couple private fields. One is to store the attached CharacterController component, and the other will be used to store a reference to the player’s Transform. We’ll talk about how to grab the player’s Transform shortly, but for now let’s write some code to move our enemy around.

void Start()
   controller = GetComponent<CharacterController>();

void Update () 
   Vector3 direction = player.position - transform.position;
   direction.y = 0;

   transform.rotation = Quaternion.LookRotation(direction);

   controller.Move(transform.forward * speed * Time.deltaTime);

The first thing we do in update is get the direction between the player and our enemy. To get the direction between any two points in space, you subtract the origin from the target, which in our case is the enemy and the player, respectively. You can draw out some points on a piece of paper to test this.

Subtracting B-A gives us the vector in red, which is (3,3). This vector can be reduced down to (1,1), or perfectly diagonal.

Subtracting B−A gives us the vector in red, which is (3,3). This vector can be reduced down to (1,1), or perfectly diagonal.

We then set the amount in our vector to zero, since we don’t want our care if how much the player is above or below us: we just want to know the direction on the ZX plane. Once we have the direction we call upon our old friend Quaternion.LookRotation (explained in Lesson 9) to rotate the enemy in the proper direction. Lastly, we call CharacterController.Move to translate the enemy in his forward direction (which currently should be facing the player), multiplied by speed, and then multiplied by deltaTime to make it framerate independent.

This is all well and good, but astute readers have likely spotted a problem by now: how do we assign the player’s Transform into our player variable? To do this, go back in to the Editor and select our character. At the top of the Inspector (just below her name), you’ll see a dropdown titled “Tag”, with the current value being Untagged. Change that to Player.

Back in our script, add the following line to the Start method.

player = GameObject.FindWithTag("Player").transform;

Baller. We can now run the project and our enemy will track the player, moving slowly towards her. This is pretty neat, but right now the enemy turns towards the player way too fast. You can see this by jumping over the enemy: he’ll just snap instantly towards you. Let’s fix this.

Instead of having our rotation be immediately set to the direction between the enemy and the player, let’s instead take our current direction and smoothly move towards our target direction. Modify the rotation line to be the following:

transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.LookRotation(direction), turnSpeed * Time.deltaTime);

We’re using a new method here, Quaternion.RotateTowards. This method takes in two rotations: a “current” and a “target”, as well as a float that defines how far to travel between the two. Save and run the project, and you’ll see the enemy now takes about two seconds to fully rotate towards the player (when pointing in the opposite direction).

The suspense.

The suspense.

As a final touch before we close out this lesson, add the EnemyHealth script to the enemy to allow us to destroy him with our rockets. In the next lesson, we’ll add in some code to give the enemy the ability to damage and destroy the player.

Lesson 14 Complete Project

Thanks for reading! If you have any problems with the above tutorial, general comments or suggestions, please post below. It’s always appreciated!

2 thoughts on “Unity Beginner to Hero Part 14: Enemy Units!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s