Boss Fight: Stage 3 — Firing

In this stage, we are going to add the Boss’ Firing behavior. The firing behavior is going to change through the different stages of the Boss Fight. Here are the different stages…

  1. Boss w/ Shield
  2. Boss w/o Shield
  3. Boss w/ All Canons Destroyed

Phase 1: Boss w/ Shield

First, let me quickly go over the setup of the Boss Canons. Each canon is set to a child of the Boss.

With each canon have a Firepoint, where the projectile will fire from.

We will need access to these GameObjects, so we are going to create empty arrays in the script and we will assign each in the Inspector.

All three of these canons will follow the movement of the Player. In doing this we will need the direction the canons will need to face by creating a local variable direction in the Update and subtract the Boss’ position from the Player’s position.

Looping over each of the canons we need to set the transform.up to move towards that direction with a rotation speed. This will have each of the canons follow the Player.

When the Boss has its Shield Generators and Shield, the Firing behavior will be simple with each of the canons firing one at a time at the Player.

We are going need to get a handle on the projectile so we can Instantiate at the firepoint of the each canon. Also, we will need to create bool to let to turn on and off the firing canon and an int to set which canon is firing.

Below is the projectile script.

Using a coroutine, which allows us to pause the program for a set of time, when canFire is true, we are going to create an instance of the projectile prefab at the location of the firepoint of the currentCanon index of the array. Then we are going to set canFire to false to prevent it any firing. We will wait a certain amount of time then increment to the next canon. We will need to check to see if the current cannon reaches the the last firepoint in the array we need to set the current back to 0. Finally, when all of that is done we set canFire back to true so we can Instantiate a new projectile at the next firepoint in the array.

When the Shield Generators are destroyed we will reduce amount of wait time between each firing. So, a float variable is created and put in the WaitForSeconds.

Where the Shield Generators are all destroyed we reduce this fireDelay, so the projectiles will fire faster.

Phase 2: Boss w/o Shield

When the shield is destroyed, all of the Canons will fire at the same time.

I am going to use a different timed firing system. We will need to declare two float variables with one being the amount of time to pass between each shot and the other holding the last time the canons fired.

If the Shield is destroyed, we will check to see if the time that is passed is greater than the last time the canons fired plus the fire rate. If it is greater than we will loop through each of the firepoints and Instantiate a projectile. We will need to set the _lastTimeFired to the current time.

Phase 3: All Canons Destroyed

We need to know when all of the canon GameObjects have been destroyed, so we are going to use a bool variable to track this and we need to change the Canon and Firepoint Arrays to Lists. This needs to be done because we are going to be destroying the canon GameObjects which will alter the amount of the array length. Arrays are static, you cannot really add or remove from them easily, but with Lists you can.

In the Laser Script, when the OnTriggerEnter event runs we will check the tag of the Canon it hit and destroy that Canon GameObject.

When a Canon GameObject is destroyed we need to remove it from the Canon List. This is done in the Boss Script where we are looping over each of the canons to move them towards the player. We perform a check of the element to see if one is missing(null) and if there is we will remove that Canon for the Lists. Also, another check is performed to see if the List count is 0 (meaning all of the elements have been removed or all of the Canons have been destroyed). If that is the case we set the Canons Destroyed to True.

This will start the Final Firing Routine, which will be a spread shot every so often.

In setting this up, several empty GameObjects we create (FPs) and we placed in the same location. The difference between this FPs GameObjects are their rotation. All of them are point a different degree amounts and when the projectiles are instantiate they will move forward at that rotation.

Conclusion

The firing behavior for the Boss differs depending on if it has its shield, if it doesn’t have a shield and if the canons are destroyed. I will need to clean up and organize the code, but I have it working! Cheers!