Health System

The Need

I have been continually developing a flexible and in depth health system in C# for Unity game development, starting in August 2023. Creating a new health class for every project has gotten repetitive, so I decided to make a universal Health class to be dragged and dropped into any of my projects. I have created numerous health scripts prior to this, giving me a great starting place. I used NaughtyAttributes to help me make my Unity component designer-friendly.

Progression

I started my Health system during class project in which I had to write another Health class. In this project I created a Damage class that would utilize Unity Collisions to detect objects with health components and remove a set amount of health. The Health system was composed of several cool features.

I always try to make my code designer-friendly. I began by using NaughtyAttributes, in which I utilized the [BoxGroup] attribute to organize each feature into subsections inside my component display.

During my VR Game Jam project, I added my health system to save us time from writing our own health class. I added UnityEvents for OnHurt and OnDeath, so that spawning sound effects and visual effects are easy to do from the editor. Following this, I included a set of bool flags in the inspector to toggle drop-downs for each feature, using the [ShowIf] attribute from NaughtyAttributes. This reduces clutter by hiding unwanted features from the component display and organizes features into dropdown menues.

At the start of developing Pariah, I added my health and damage system and sought out to utilize the NaughtyAttributes [EnumFlags] to organize the inspector more. This gave me the opportunity to learn bitwise functions for the first time. Later on with guidance from a peer, I remade the damage class as a static class. I gave it a public function to create a Physics box cast to check for all colliders in an area, and deal damage to them. I created a better system for health IDs, using a helper class to define health IDs and the other IDs they can interact with.

But, this damage system comes with its caveats. Converting to a static class removes the ability for designers to adjust attacks with ease. It also makes changing attacks over time more difficult. There is also no existing way to visualize the hit boxes for attacking. After noticing this, I retrieved the code for my old non-static Damage class that would deal damage with unity collisions.

Next Steps

For the future, I plan to create a more robust damage system with the ability to inflict effects, such as knockback, or burn. I am currently working on a networked side project, and will also create a version of my health system that is compatible with Photon Networking.

Features

At the time of writing, the health system features the following:

  • Static class that casts a box and deals damage
  • Collision damage class
  • Health class featuring:
    • Shields
    • Regeneration
    • Knockback
    • Invulnerability 
    • Hurt Events
    • Death Events

This was one of the first times I have used Unity Events, and it has proved to be immensely helpful. The component allows to assign all behaviors for hurt and death onto one simple event. For example, I created this health bar effect and trigger it through the OnHurt event.

Outcomes

I've build and maintained a health system with a collection of other scripts. It's a great solution to add health to any game and I love getting the opportunity to add it into my projects.  While it isn't applicable to everything, I've began a strong collection of scripts that can be adapted or built from in any given project.

I've learned that damage isn't a cookie cutter system like health. Depending on the type of game, it will have vastly different applications of damage. In shooters and RTS games, a box cast is not an effective solution for dealing damage. For fighting games and other games with frame-perfect hit boxes, the hit boxes and damage need to be simply defined and changed, which my system does not. But for a melee roguelike, my current damage system works pretty well.