Event Management Design Proposal

Event Management Design Proposal

In a Singleton class such as the GameManager, it can be initially useful to handle all events. However, as the game grows, it becomes increasingly problematic for the GameManager to handle every minor event, making the codebase more complex and harder to maintain. At this point, it becomes essential to separate event management into dedicated classes.

Problems with Managing Events in GameManager

When the GameManager handles all events, game logic and UI-related code get mixed together, which makes maintenance difficult. Moreover, as the number of events grows, the GameManager becomes larger and increasingly violates the single responsibility principle. For example, managing bonus score increases, UI updates, player state changes, etc., all within the GameManager, leads to limited scalability and complexity.

The Solution: Dedicated Event Classes

By introducing dedicated event classes, the GameManager no longer needs to manage all events. Instead, we can delegate event handling to classes that handle specific events. Importantly, these event classes can be made static, allowing the GameManager to simply manage the events, while other classes handle the actual event processing.

Real-life examples:

  • PlayerEventManager: Handles player-related events (e.g., score increases, player state changes, etc.)
  • UIEventManager: Handles UI-related events (e.g., button clicks, screen animations, etc.)
  • GameStateEventManager: Handles game state-related events (e.g., game start, game over, etc.)

Event Class Structure Example

// Handling player-related events
public class PlayerEventManager
{
    public static event Action OnScoreIncreased;

    public static void IncreaseScore()
    {
        OnScoreIncreased?.Invoke(); // Trigger score increase event
    }
}

// Handling UI-related events
public class UIEventManager
{
    public static event Action OnGameOver;

    public static void TriggerGameOver()
    {
        OnGameOver?.Invoke(); // Trigger game over event
    }
}

// Handling game state-related events
public class GameStateEventManager
{
    public static event Action OnGameStarted;

    public static void StartGame()
    {
        OnGameStarted?.Invoke(); // Trigger game start event
    }
}

Event Class Usage Example

// GameManager subscribes to and handles events
public class GameManager : MonoBehaviour
{
    void OnEnable()
    {
        PlayerEventManager.OnScoreIncreased += HandleScoreIncreased;
        UIEventManager.OnGameOver += HandleGameOver;
        GameStateEventManager.OnGameStarted += HandleGameStarted;
    }

    void OnDisable()
    {
        PlayerEventManager.OnScoreIncreased -= HandleScoreIncreased;
        UIEventManager.OnGameOver -= HandleGameOver;
        GameStateEventManager.OnGameStarted -= HandleGameStarted;
    }

    private void HandleScoreIncreased()
    {
        Debug.Log("Score Increased");
    }

    private void HandleGameOver()
    {
        Debug.Log("Game Over");
    }

    private void HandleGameStarted()
    {
        Debug.Log("Game Started");
    }
}

Conclusion

Managing all events in the GameManager is fine initially, but as the game grows in complexity, it becomes difficult to maintain and scale. By introducing dedicated event classes, the responsibility for handling events is clearly separated, improving both maintainability and scalability. Using static event classes allows for efficient event management while keeping the GameManager's role limited to event management. This approach ensures that the GameManager does not become overburdened with responsibility, leading to cleaner, more manageable code.

The GameManager no longer needs to handle all events, and each event management class takes responsibility for its specific event, allowing for greater flexibility in the game design.

Popular posts from this blog

Understanding Arrays as Reference Types in C#

Setting Up a Basic Follow Camera with Cinemachine 3.x

Understanding and Using ? (nullable) in C#