- Unity 2020 By Example
- Robert Wells
- 941字
- 2025-02-28 16:26:48
Creating a Health component
Both the player spaceship and enemies need health. Health is a measure of a character's presence and legitimacy in the scene, typically scored as a value between 0-100. 0 means death, and 100 means full health. Health is, in many respects, specific to each instance: the player has a unique health rating, and the enemy theirs. There are nevertheless many things in common, in terms of behavior, between player and enemy health, that it makes sense to code health as a separate component and class that can be attached to all objects that need health. Create a new class called Health, which should be attached to the player and all enemies or objects that need health:
public class Health : MonoBehaviour
{
public GameObject DeathParticlesPrefab = null;
public bool ShouldDestroyOnDeath = true;
[SerializeField] private float _HealthPoints = 100f;
}
The Health class maintains object health through a private variable, _HealthPoints. The _HealthPoints variable is declared as a SerializedField, allowing its value to be visible in the Inspector while maintaining a private scope, in other words, not accessible by other scripts. The prefab variable, on the other hand, is public, allowing its value to be both seen in the Inspector and changeable from elsewhere in the code if needed.
We want to be able to change the _HealthPoints variable from another script and have some logic to check for when it reaches zero. We could create a setter function to accomplish this, but instead, we'll make use of C# properties:
public class Health : MonoBehaviour
{
…
public float HealthPoints
{
Get { return _HealthPoints; }
Set
{
_HealthPoints = value;
if(HealthPoints <= 0)
{
SendMessage("Die", SendMessageOptions.DontRequireReceiver);
if(DeathParticlesPrefab != null)
{
Instantiate(DeathParticlesPrefab,
transform.position, transform.rotation);
}
if(ShouldDestroyOnDeath) { Destroy(gameObject);
}
}
}
}
}
Let's summarize the preceding code:
- _HealthPoints is now accessible through a C# property, HealthPoints. This property features both get and set accessors to return and set the health variable.
- The Health class is an example of event-driven programming. The class could have continually checked the health of the object in an Update function. Instead, the check for death is made during the C# property set method. This makes sense because the properties mutator is the only place where health will ever change. Not having to check the health of every object on every frame saves a lot of work. Imagine if you had thousands of objects on screen at once, and each one was constantly checking its own health! You'd see a significant performance increase by writing event-driven code.
- The Health class uses the SendMessage function that lets you call any other function on any component attached to the object by specifying the function name as a string. In this case, a function called Die will be executed on every component attached to the object (if such a function exists). If no function of a matching name exists, then nothing happens for that component. This is a quick and easy way to run customized behavior on an object in a type-agnostic way without using polymorphism. The disadvantage of SendMessage is that it internally uses a process called Reflection, which is slow and performance-prohibitive. For this reason, SendMessage should be used infrequently. More information can be found online at https://docs.unity3d.com/ScriptReference/GameObject.SendMessage.html.
When the health script is attached to the player spaceship, it appears as a component in the Inspector. As shown in Figure 3.17, it contains a field for Death Particles Prefab:

Figure 3.17 – Attaching the health script
This field is optional (it can be null), and is used to specify a particle system to be instantiated when the health of the object reaches zero. This will let us instantiate an explosion particle effect when the player dies. But first, we have to create one.