In my last article, I got all of the animations and triggers working on my boss. My objective for this article is to create a health system with a corresponding UI. Let’s get into damaging this creature!
I get started in the AnglerfishTarget class, which is the script that’s on the target object that will be dealing with damaging the boss. I create three int variables to handle the health. One for the current health of the boss, one for the minimum health value and another for the maximum health value. A float variable is declared for the magnitude of the camera shake that will let the player know they hit the target. A variable is declared for the Camera Shake script, and another to access the health bar script.
In void Start, I use GameObject.Find to look for the Camera_Holder game object, and then grab the camera shake script component. The health bar has a Tag of HealthBar, so I find that object by looking for it’s tag, and then grab the health bar script. The camera shake magnitude is assigned a random range between 0.2 and 0.4, which will add a little variety to the shake whenever it triggers. Lastly, the current health value is set to be max health.
A public method is created for the player projectiles to trigger upon collision with the target. This method requires an int value to be passed through, which will let the different projectiles deal their own unique amount of damage. When called, the damage value passed through is removed from the current health value. Next, a local int variable is introduced (anglerHealthClamp), to clamp the health value between the minimum and maximum values allowed. The current health variable is then assigned the value of the clamp, which will keep the boss health from diving into the negative. I already have the health bar in place, which I will get into shortly. For now, I call the health bar script and ping the public Update Health method, and pass in the current health value of the boss. In the last statement, the public coroutine on the Camera Shake script is called, and the duration and magnitude of the shake is passed through.
This gif shows health dropping off the boss in the inspector while getting attacked.
This gif shows that the camera shake is fully functional!
Jumping over to the projectile class momentarily, I get into the OnTriggerEnter method where I am checking tags with the projectile before performing an action. This here is in the middle of a few if else statements where I check for the AnglerTarget Tag. A local variable is declared for the AnglerfishTarget script, and then I use GetComponent through the collision. If the target is still alive, the public damage method is called and the required damage value is passed through. In this case, the Tusk projectile will be dealing 5 damage to the boss!
Before diving into the health bar mechanics, I make some vector based heath bar assets in Corel Draw.
Being that I want to change the color of the fill area on the Sprite Renderer, and the color is really just a tint, I export a black and white version of the fill to better absorb the tint color assignment. From left to right I have the foreground layer, the background layer and then the middle fill layer that will receive the health bar script.
After bringing these assets into Unity, the fill sprite needs an adjustment in order to work properly. I open the Sprite Editor to chance the standard centered pivot point to be in the left position. This will enable the image to scale from the right side to the left, rather than both sides towards the center. I’ll show a visual example next. Also to note, I make these objects into prefabs, adjust their sorting layers and child them to the boss parent prefab.
As you can see here, when I manually adjust the X scale on the health bar fill transform in the inspector, the image on the left shows it scaling right to left…just what is needed for a health bar!
Now to get going on the health bar script with some variables. I add an int variable to represent the maximum health of the boss. Green and Red color variables are added because I want these to represent full and low health on the health bar visual. In order to do this, I need another variable for the Sprite Renderer on the fill layer of the health bar, which is what this script is attached to. The last variable is of type Vector3, to store the local scale of the health bar for adjustment.
In void Start, I use GetComponent on the Sprite Renderer, the color of the health bar is set to be the max health color (green), and then the health bar scale variable is assigned the value of it’s own transform, then using dot notation to dive into the local scale on the transform.
The Health Bar class has a public method called UpdateHealth that is called by the boss target whenever it gets hit. It takes in an int value for the current health being amount passed from the target. A local float variable is declared to store the current fill amount of the health bar. This value needs to be between 0 and 1 to work with the local scale on the transform, so the current fill amount is assigned the value of the current health divided by the maximum health. If the boss has 50% health left, 50 divided by 100 is 0.5, which is exactly what I need to properly adjust the local scale of the fill object. The main thing to note here is that I am dividing two integers to get a float value, so I cast the int values as float in the equation to keep the information after the decimal place. I only want to change the X value on the local scale, so it is referenced through dot notation, and then assigned the value of the current fill amount. Next, the local scale of the health bar fill object is accessed via it’s transform, and it is assigned the value of the health bar local scale variable. The final line uses Color.Lerp to assign the value of the Sprite Renderer on the health bar. This uses the max health color and the min health color, and interpolates between them using the current fill amount variable. When the boss takes damage, the color of the health bar will now smoothly change from green to red.
Well, that’s it for damaging the boss! I hope you join me in my next article where I start giving the boss some way to attack the player. Thanks for reading!