Previously I implemented UI elements to tell the player the most vital info, their character's stats and abilities. Now I have moved on to implement the next most important category of information, the status of the enemies.
The first step to doing this was to add an enemy health bar. I began by creating a new UI canvas in the scene and set its render mode to world space. I then added a UI slider object as its child and deleted any unnecessary decorative elements. I then dragged this canvas into the resources folder and deleted it from the scene, making it a loadable prefab. The transforms and anchors of each object in the slider had to be tweaked to ensure the right look, here some images showing the object hierarchy and transforms:
To ensure it will always be facing up towards the camera, I rotated the health bar object containing the slider by 45 degrees in the X axis. To match the health bar of the player, I also coloured the health bar fill red.
I mentioned that we want this as a loadable prefab, this is because we are going to need to spawn it in after an enemy spawns. This is necessary because we will not be adding the health bar to the enemy prefab as we do not want it to be a child of the enemy character. Childing the health bar to the enemy would be helpful in that it would ensure that it followed the character's position, but it would also make it follow its rotation, turning the health bar away from the camera. To circumvent this issue, the health bar will be a separate game object to the character but will contain a script which causes it to follow them around. Here is the contents of that script.
As you can see, this script uses the parent character's position, but the canvas is not a child object, so where is this parent character? Well, although it isn't a child object to avoid the rotation issue, we set this parent character variable as the character which spawns the canvas to allow it to still track its position. This spawning is done within the start function of the enemy controller script. The base character script already has a health bar object reference used by the player, so here we just instantiate our new overhead health bar, set the health bar reference to refer to it, set its parent to be this character and then set it to inactive alongside a bool tracking if it is active or not. So now we have a overhead health bar following the character, and a reference to it. We set it to be inactive as we don't want the bar visible when the character is not in combat to reduce visual clutter.
This overhead health bar has its fill percentage modified by the take damage and take healing functions in the base character just like the player's health bar, but I did make some additions to allow for the show/hide functionality. When the character takes damage, if their health bar is inactive, it is activated before being modified to show the character's health percentage. We then stop and start a "hide health bar" coroutine. We stop then start it so that if it is already running, it will restart again from the beginning.
Once the health bar is made active and the coroutine is called, if no damage is dealt to the character for 5 seconds, the bar is deactivated again.
An enemy health bar is a nice start, but to really understand what is happening in combat, we need combat text. These are floating notification which appear whenever something happens like damage being dealt, healing being received and effects being applied. Similar to the overhead health bar, the combat text is a prefab in the resources folder containing a world space UI canvas. A UI text object is also set as a child of this canvas and the font size is set to a tiny 0.5. Here are the transforms of those objects.
I added a spawn combat text function to the base character. This instantiates a combat text object at a random spot near the character's head whenever it is called. The content and colour of the text vary depending on what has caused the spawn. This means the text can be used to convey lots of useful info to the player. This function takes two inputs, a quantity float and a text type string. The quantity is what number will be show of course, the type determines the colour. If quantity is 10 and type is damage, then the text will be "-10" in red. If type is neither damage or healing, that means it is an effect and so could be positive or negative, aka a buff or a debuff. Buffs (positive) are coloured cyan, debuffs (negative) are magenta, but this is subject to change. For effects I also add the text type to the text output to explain what stat is being effected.
This function is called in various places. As you may have noted earlier, it is called by the take damage function.
It is also called by the taking healing function like this to ensure the text only displays the actual healing dealt:
Calling this function for effects is a bit more complex. Over in the infamously long mod stats function of the effect script, after any stat is modified, we call the spawn combat text function to display this. For percentage mods it looks like this:
For flat mods it is a little simpler:
Once a stat mod expires, in the remove effect function, we call spawn combat text again but with the value multiplied by -1. This means that if a 10 armour buff wears off, it will show up as -10 armour in the combat text and will be coloured appropriately. For percent mods we use the applied value so it looks like this:
For flat mods it looks like this:
Here is a video of the enemy health bar and combat text in action:
Comments