Day 45 — Improvements: dodging enemy

Connor Fullarton
4 min readApr 29, 2021

--

Hey and welcome!

This one is a fun one, we’re going to be creating a new enemy that will slowly move down the screen in a straight line and occasionally fire a laser. The difference here though is that this enemy will actively dodge the lasers that the player fires off at the enemy making it pretty tricky to destroy.

As usual let’s go ahead and create a new game object as the enemy and add in all the necessary components. Since I’m still prototyping I’ve borrowed the current enemy and made them green:

With that settled let’s create a new script for your enemy and attach it, I called mine DodgeEnemy. Now there’s quite a bit of logic that we’ll need to add in so let’s start by looking at the methods and coroutines that are unique to this enemy:

private bool _dodgeRight = false;
private bool _dodgeLeft = false;
private bool _dodging = false;
public void DodgeLaserRight()
{
if (_dodging == false)
{
StartCoroutine(DodgeLaserRightRoutine());
}
else
{
return;
}
}
public void DodgeLaserLeft()
{
if (_dodging == false)
{
StartCoroutine(DodgeLaserLeftRoutine());
}
else
{
return;
}
}
IEnumerator DodgeLaserRightRoutine()
{
_dodging = true;
_dodgeRight = true;
yield return new WaitForSeconds(0.5f);
_dodgeRight = false;
_dodging = false;
}
IEnumerator DodgeLaserLeftRoutine()
{
_dodging = true;
_dodgeLeft = true;
yield return new WaitForSeconds(0.5f);
_dodgeLeft = false;
_dodging = false;
}

We’ll deal with the actual movement afterwards so first we’ll look at what determines the state of dodging that the enemy is in, whether they should be dodging to the left or the right.

To do that we’ve created two variables called _dodgeRight and _dodgeLeft and then a third variable called _dodging to determine whether or not the enemy is already in the process of moving to the left or right. So with this code the enemy will only be able to move left or right if _dodging is false.

When _dodging is false it starts a coroutine to make it true along with either _dodgeLeft and _dodgeRight depending on which method is called. We set this to happen for just half a second so that it’s a relatively quick movement. Speaking of movement let’s go ahead and make some alterations to that making use of our variables.

private float _horizontalSpeed = 4.0f;if (_dodgeRight == true)
{
transform.Translate(new Vector3(1, 0, 0) * _horizontalSpeed * Time.deltaTime );
if (transform.position.x >= 9.7f || transform.position.x <= -9.7f)
{
_dodgeRight = false;
}
}
else if (_dodgeLeft == true)
{
transform.Translate(new Vector3(-1, 0, 0) * _horizontalSpeed * Time.deltaTime );
if (transform.position.x >= 9.7f || transform.position.x <= -9.7f)
{
_dodgeLeft = false;
}
}
else if (_dodgeLeft == false && _dodgeRight == false)
{
transform.Translate(new Vector3(0, -1, 0) * _verticalSpeed * Time.deltaTime);
}
if (transform.position.y < -5.3f)
{
_dodgeRight = false;
_dodgeLeft = false;
transform.position = new Vector3(Random.Range(-9.5f, 9.5f), 6.2f, 0);
}

There’s quite a bit of code here but the important part to note is that we stop the vertical movement when _dodgeLeft or _dodgeRight is true and substitute horizontal movement to the left or the right depending on which bool is true. Then we’re making use of our first instance of the || (or) operator in transform.position.x >= 9.7f || transform.position.x <= -9.7f. This just reads that if the position of the enemy is greater than 9.7f or the position is less than -9.7f. We’ve got this here because we don’t want our enemy moving beyond the borders of the game. By setting the _dodgeLeft or _dodgeRight to false here we’re overwriting the coroutines.

After the if statements for dodging we have an else if that handles the regular vertical movement to the bottom of the screen when _dodgeRight and _dodgeLeft are false. Then for good measure we set them to false as well in the last if statement that tracks when the enemy hits the bottom of the screen.

If you serialize the fields for the dodge left and right bool and test them in the inspector this should work pretty well for you so now it’s time to add in the code that calls our dodge methods.

private DodgeEnemy _dodgeEnemy;if (GameObject.Find("DodgingEnemy(Clone)") != null)
{
_dodgeEnemy = GameObject.Find("DodgingEnemy(Clone)").GetComponent<DodgeEnemy>();
}

Over in our Laser script I’ve added the above code into the start method in order to get a reference to our new enemy script so that we can make use of it here in the MoveUp() method:

if (_dodgeEnemy != null)
{
float distanceY = _dodgeEnemy.transform.position.y - transform.position.y;
float distanceX = _dodgeEnemy.transform.position.x - transform.position.x;
Debug.Log(distanceX);

if (distanceY < 5.0f)
{
if (distanceX > 0f && distanceX < 1.0f)
{
_dodgeEnemy.DodgeLaserRight();
}

if (distanceX < 0f && distanceX > -1.0f)
{
_dodgeEnemy.DodgeLaserLeft();
}
}
}

Similar to what we did when the enemy fired off a laser at the powerups I’ve put in some code to work out the x and y distance between our laser and new enemy. The important one is our x distance though since when it’s greater than 0f we set the enemy to dodge right and when it’s less than 0 we set them to dodge left.

Pretty cool right? The difficulty is really ramping up now, the only way we can destroy this enemy is to catch it between two lasers or get it caught on the sides of the game. The next thing we’re implementing for the game though will help to destroy the enemy.

--

--

Connor Fullarton
Connor Fullarton

Written by Connor Fullarton

Hey and welcome! My name is Connor and my goal here is to put out a daily post for a full year about my game development journey.

No responses yet