How to implement a Unity game events system

To optimise your game, reduce the bugs, and allow a flexible architecture, is a good idea to use an event management system. When an game event occur, like a damage, instead of call each necessary function, to display the damage effect, reduce the health, etc…, you can let all the related function register to an damage event, and trigger the event from the damage control when a damage happens. In the future if you need to create a new functionality that depends on the damage, you can just register to this event, instead of try to remmember all the places and condition where the damages occur.

To implement an event system you can use the class bellow. This class represent an event distribution channel. When an event happens at the game, this channel distribute the event to the subscribers.All the functions that need to react to a game event register:
EventChannel.AddListener(MyAction);
The part that generate the event call
EventChannel.TriggerEvent(parameters);

To clear all the events registered:
EventChannel.clearAll();

For example, to control player damage, you create an event:
EventChannel damageEvent = new EventChannel();
As a reaction to the damage you need:
1. To paint the damage effect, so you create a funtion PaintDamage(Object gameEvent).
2. To reduce the player health, so you create a function ReduceHealth(Object gameEvent).

To initialize the event system you register both:
damageEvent.AddListener(PaintDamage);
damageEvent.AddListener(ReduceHealth);
When the player receive a damage, like a shot, the function that detect the shot call:
damageEvent.TriggerEvent(parameters);
All the functions that subscribe to damageEvent with AddListener, will be called.

// Class that represent one event channel
// For each channel you instantiate this class
//     EventChannel newEvent = new EventChannel();
//

public class EventChannel {
  
  // Delegate functions to create call back actions
  public delegate void ActionCallBack (Object gameEvent);

  // Store all subscribed call back action
  public ActionCallBack gameActions;

  // Register a subscriber call back action
  private ActionCallBack RegisterEvent
  {
    get { return gameActions; } // Get subscription list
    set { gameActions = value; } // Set subscription list
  }

  // Register call back actions
  public void AddListener(ActionCallBack action) {
    RegisterEvent += action;
  }

  // Clear all subscribed call back actions
  public void clearAll() {
    // Get all current subscribed events
    System.Delegate[] allEvents = gameActions.GetInvocationList();

    foreach (System.Delegate del in allEvents) {
      gameActions -= (ActionCallBack) del;
    }
  }

  // Call to send an internal event to registered functions
  public void TriggerEvent (Object gameEvent)
  {
    // Call all registered actions
    if (gameActions != null)
      gameActions (gameEvent);
  }
}