Creating a Boss Fight with Multiple Phases
Today’s article will focus on explaining a simple way to add and change between different phases. For the sake of concision, only one of the phase patterns will be covered as an example, the others will be in their own article.
Objective: Change the Boss’ attack pattern depending on how much HP it has left.
Changing Between Phases
This article assumes that you have a working method to keep track of how much HP the Boss has at a given moment, and to take damage. If you haven’t already, you can follow along with these articles to get your HP Bar set up!
Creating a Dynamic HP Bar in Unity
Today’s article is part of a Boss Fight Script that we’ll keep exploring in segments due to its length.
Programming a Dynamic HP Bar in Unity
Today’s article is part of a Boss Fight Script that we’ll keep exploring in segments due to its length. This article…
- Chose at what HP percentages or quantity your boss will go from phase to phase. In my case, my boss will have three phases:
- Phase 1 = 100% HP → Green Health Bar
- Phase 2 = 50% HP → Yellow Health Bar
- Phase 3 = 30% HP → Red Health Bar
Note: If you want to learn how the HP percentages are appended to color, check this out!
2. Create a method to keep track of the phases. Here I am using if-statements, but this can be done with a Switch-case as well. This method should be called from the Update. As the Boss takes damage and the conditions are met, the methods or logic within the if-statements will execute.
Note: You might also want to keep track of whether your Boss object is alive or not.
- You can change the conditions as you see fit for your game, in my case, choosing less or equal made sense because the first two patterns are the same with phase 2 being a more aggressive version of phase 1. The added aggression is controlled externally in a Script that handles the Omnishot Attack behavior that you can see in the following image.
Note: The Boss Omnishot script will be discussed in its own article due to its lenth and complexity.
- The reason why phases 1 and 2 are in this method despite being handled externally, is to control the damage visuals which give the player feedback on how the battle is progressing in their favor.
- Damage Visuals are optional, but if you wish to add them to your Boss Phases, I’m using the same exact logic discussed for the Player Damage Visuals down below.
Boss Phase Pattern Example — Side To Side Laser Attack
When the Boss’ health bar reaches a critical state of 30%, its attack pattern changes to a wide-laser attack in which the boss moves from side to side. The laser itself lasts for a limited time, but the boss retains the side-to-side movement. Let’s break it down!
- In the Boss Script, declare global variables for the laser object and Side-To-Side Movement.
- The laser variable will be a SerializeField to assign it in the Inspector. Once assigned, we’ll deactivate the object in the Hierarchy for now.
- _distance will be how wide the side-to-side movement is
2. Create a method for the laser attack. This will have the movement behavior and we’ll activate the laser visualizer here.
- The altMovement vector is initially set to the object’s default position because we want the boss to remain in the same area but move in the X-axis.
- altMovement.x makes use of the _distance variable multiplied by Mathf.Sin. Mathf is a library within Unity that allows us to use a variety of common math features, including trigonometry.
- Using Sine allows us to lock the movement between -1 and +1 in a side-to-side motion. Since we don’t have a variable to manipulate the amplitude we won’t see changes in the y-axis movement of our object. Instead, we make use of our distance variable to see how far the motion stretches across the x-axis alone.
Using a Sine wave can even allow us to create a zig-zag movement if we had a variable to control the amplitude along the cycle. I actually have an article where we do just that for an alt enemy movement!
- The object’s transform/default position is set to altMovement now that we have defined what altMovement means.
- The Laser Visualizer is set to active.
Making the Laser Attack Last a Limited Time
Create another script to attach it to the laser object. This script will execute once we activate the object from the Boss script.
- We’ll be using a coroutine to limit the Laser attack to a set number of seconds. Alternatively, you can set other ways to activate this coroutine so that the attack can happen several times during the same phase. However, in my game, this is an opening attack for the final phase and it only lasts about 5 seconds because the difficulty spike feels more balanced this way.
Note: You can learn more about coroutines down below.
Coroutines with Unity!
Anyone who has programmed in Unity knows that sooner or later you’ll end up amassing a considerable amount of methods…
2. I decided to set my collision logic to make this laser attack damage the Player on this script as well.
Note: You can learn more about collision dectection here:
OnCollisionEnter vs. OnTriggerEnter — When to use them
Colliders are added to GameObjects to reflect their physical structure and to simulated real-world physics.
The side-to-side movement will continue throughout the final phase after the laser attack, this makes dodging and landing hits more difficult for the Player.
This has been part of a series of Core Programming Challenges from GameDevHQ. In the next article, I will continue discussing the Boss Fight Code by going through phases 1 and 2, which have lengthier, more complex scripts.