0
\$\begingroup\$

Broadly speaking, this is a question about how to separate my game object's code into distinct feature components that can be added and removed as needed.

More specifically, I am trying to achieve this using C# events in Unity. But I am open to other solutions.

Scenario: We have enemies that have health. When their health reaches zero, they die. Some enemies (think asteroids) may spawn a number of child enemies (think smaller astroid pieces) when they die. Others however, just die.

I want to have two scripts:

  • EnemyHealth: Tracks the enemy's health and kills the enemy when its health reaches zero.
  • EnemyChildrenSpawner: Spawns child enemies after the enemy's death

This way, all enemies will have the EnemyHealth script, and some enemies will have the EnemyChildrenSpawner script in addition.


My idea is to have the EnemyHealth script raise an event when the enemy dies, and have EnemyChildrenSpawner subscribe to said event to spawn the children.

What would be the best way of achieving this?

Here's my attempt. It works. Just not sure if this is good practice, especially using the GetComponent in the second script?

EnemyHealth.cs

public class EnemyHealth : MonoBehaviour
{
    // The event to invoke when this enemy died
    public event EventHandler OnDied;

    // Gets called when this enemy's health reached zero
    private void Die()
    {
        // Invoke the died event
        OnDied?.Invoke(this, EventArgs.Empty);

        // Destroy this enemy
    }
}

EnemyChildrenSpawner.cs

public class EnemyChildrenSpawner : MonoBehaviour
{
    private void OnEnable()
    {
        GetComponent<EnemyHealth>().OnDied += SpawnChildren;
    }

    private void OnDisable()
    {
        GetComponent<EnemyHealth>().OnDied -= SpawnChildren;
    }

    private void SpawnChildren(object sender, EventArgs e)
    {
        // Spawn children
    }
}

```
\$\endgroup\$
1
\$\begingroup\$

Myself, I would replace this with:

public UnityEvent OnDie;

Now the event will appear in the Inspector, so a designer can use the graphical interface to link up any number of different script methods to react to the health component's death.

Those components don't need to know anything about the health component, and don't need extra code added to them to attach and detach event listeners.

This makes it easy to mix and match different death behaviours without having to hard-code every possible pairing.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.