Engaging Enemies in Unity

Foster ferocity for fully-fleshed furious foes

Micha Davis
4 min readApr 26, 2021
A deer is drinking from a river when they are surprised by a sudden (unsuccessful) crocodile attack.
Surprise!

Predictable behavior is going to get stale quickly. We need more enemies, each with their own attack style and movement. We need surprises to keep the player on their toes. We need to increase difficulty gradually over time to let the player find their groove and get comfortable, and then we need to hit them with a new angle.

Here, let me give you some space to get past the scary crocodile.

a cat pouncing toward the viewer

New Enemy Types

The first new enemy will be what I call the “Sinusoidal Weaver” — a smaller ship that waves back and forth as it travels, making it quite a bit harder to hit with our very slow “laser.”

The above image shows the sine wave oscillation effect I ended up with. Note how the ship slows and shifts at the apex of each wave. This is with the Y-axis speed set to zero, as I was just focusing on achieving the X-axis effect, which I did using another Math function: Mathf.Cos

_xSpeed = (Mathf.Cos(_time * _frequency) * _amplitude * _frequency) * Time.deltaTime;
 transform.Translate(new Vector2(_xSpeed, (_ySpeed * Time.deltaTime) * -1));

This gets me a nice wave and let’s me tweak the rate of change of position by adjusting the frequency in the inspector. I also have to flip the sign on the y axis (because multiplying a negative doesn’t get you a negative result).

The next new enemy is the “Teleporter” type. So-named because its style of movement is to wink out of existence and reappear elsewhere. This mastery over space and time doesn’t end there — this enemy also fires Black Hole projectiles, just like the player can.

It’s unfortunately difficult to see in the low framerate of this gif, but the ship actually shrinks to nothing along the x-axis before moving, and then grows back to normal size, again along the x-axis. This gives the impression that it is tilting perpendicular to reality.

This wasn’t an easy effect to achieve. I was determined to do this purely through code, rather than through animation. Getting the timing on everything just right took a lot of wiggling and fiddling. Here’s the code that makes it work:

This iterator times out the jumps, sets the coordinates, and sends signals to the script in charge of scaling the object up or down.
This is its own script because I want to reuse it for something else… later.

The scaling script can be toggled at need via the public ScaleMe method. A Vector3.Lerp smoothly squishes the x toward 0 over time, and then when the signal is given, smoothly unsquishes the x back to 1.

I wanted an enemy that had armor and mobility, like a knight… but in a space ship. So the next enemy was the “Shield Drone,” which was more named after its shape than anything. Since it was inspired at least a little by knights, I decided to give it a classic Chess Knight’s move. To pay full homage to the movement style, I opted to leave this motion rough and exact, rather than lerping in smooth arcs. And, what is a knight without their shield. I chose green to match enemy lasers.

The Drone chooses one of 8 directions at random and moves for one second in that direction. Then it randomly choses one of two directions perpendicular to the first vector and moves for one half of a second.

The code is long and could probably be streamlined A LOT, but it’s doing its job so I can’t complain much for now.

If you squint, you can just make out the process.

And then running through Update, I have:

The final enemy type is the aggressive “Rammer” which tracks the distance to the player, and if it is close enough, it turns on a boost of ramming speed.

This one was nice and easy because we already figured out how to find a target and move to it with our Black Hole projectile.

That’s all of the new enemy types I’ve added. Next article we’ll take a look at making a wave system so we can control how often we get all these new enemies.

--

--

Micha Davis

Unity Developer / Game Developer / Artist / Problem Solver