Challenge 5 completed!: Implement a new enemy!
Yesterday, we shared the trials and tribulations of overcoming this challenge, but now let’s look at our triumphant conclusion! Let’s get to the code!
You never really want to hardcode anything as things like screensizes can change so for the borders of the screen, I created 4 variables for the x and y axis that the enemy couldn’t float past.
Next PauseTimer is the variable we use to pass time into the WaitForSeconds() method. _pauseTime is how many seconds the enemy waits before moving on to the next point in space.
Since the enemy needs a few more seconds to shoot, instead of hardcoding something like _pauseTime+2f, I figured go with best practices and create a new variable to hold that new amount of time.
_isAlive, we’ll need this to trigger some events when the enemy dies.
_shotsToKill is just that. How many shots to kill this enemy. It’s got a [SerializeField] in front so anyone can change the amount in Unitys inspector window. This enemy should probably take at least a dozen hits so we’ll type that in.
_enemy speed is self explanatory. 3 is a good slow moving amount, we can just leave it initialized like that.
_nextWavePoint is generated by a random algorithm. I left it serialized so I can see the numbers being generated. I’ll probably take it out later.
_fireCount is how many times the enemy should move from point to point before firing the laser. _fireCountDown is just a private variable our program uses to help us actually do the countdown (or up as it were).
Next we create a couple holders, one for our laser, and the other for some explosions we’ll generate when the enemy dies. As an aside, I drew around 6 frames of an explosion and using an awesome application called BitmapFlow, I was able to interpolate those 6–7 frames into 30 or so for a smooth explosion effect! If you feel this spritesheet would be useful to you, go ahead and use it. It’s Creative Commons Attribution CC 4.0.
The enemy has its own animator for its death state, and the laser has an animator for when it gets activated and moves 45 degrees.
_anim2Play is a temporary string variable where depending on a random number, the name of the animation is put into it and then played.
In the awake function, we turn off the explosion holder immediately, that’s for when the enemy dies. We also initialize our animators.
In the Start function, we initialize our important variables and then get things rolling by picking a random point on the screen and starting the coroutine to actually start moving.
The PickARandomPoint function is straightforward, get a random point for x and y, and create a new waypoint from them.
Here’s the meat of the program! This actually does the movin’ and the ‘blastin!
Here we have a not so infinite loop with a while that ends when _shotsToKill is fulfilled. But we will be moving each frame towards the _nextWayPoint. If we haven’t reached the next waypoint, we return null and the while loop continues to move the enemy object.
once we do hit a waypoint, we’re going to see if we can fire and we can do that only if _fireCountDown has reached _fireCount. Since we’re just starting, we can assume it hasn’t so 1 will be added to _fireCountDown, the enemy will just sit there for a few seconds, and we’ll pick a new RandomPoint and the enemy will automatically move to and go through this loop until _fireCountDown does reach _fireCount. When that happens, We’ll Fire the laser, reset _fireCountdown, pick a new random point and do it all over again until the enemy dies.
That other yield return null is there in case all checks have fallen through and it hits that exit point. If that yield return null isn’t there, Unity goes nuts and our computer can freeze. It’s one of the inherent dangers of working with infinite while loops.
the FireLaser method is straightforward. Pick a number between 0 and 1*, if it’s 0, laser fires left, if it’s 1, fire right. (*Remember that if you use integers in Random.Range, it isn’t inclusive. It is if you use floats.)
Don’t worry, we’re almost done! This is the OnTriggerEnter2D Method for the enemy ship. We just do a few checks to see what’s touching its collider. If it’s our own laser, nothing happens. If it’s the player, we’ll take 3 hit points and check to see if we died. If a laser hits us, we destroy the other laser, and subtract 1 hit point and see if we’ve reached 0 hit points in DeathCheck.
The DeathCheck merely checks to see if we go under 1 hit point, and if we do, we turn on the explosionHolder, set the enemy speed to 0 so it stops. change the _isAlive boolean to false so the coroutine essentially stops too, and we set our enemy animation to _isDead, we’ll see it in action in just a moment!
DestroyEnemyShip is called inside of the death animation. the player gets anything from 50–100 points, and we destroy the enemy game object!
So let’s see this bad boy in action!
Those mini-explosions are a cool effect, aren’t they? Tomorrow, I’ll share how I created it.