Skip to content

leventeren/GenericGameEventSystem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

GameEvent System for Unity/C#

A lightweight, type-safe event system for Unity and C# projects. This system provides a simple and efficient way to implement the observer pattern without the overhead of UnityEvents or C# events.

Features

  • Type-safe: Generic implementation ensures compile-time type checking
  • 🚀 Lightweight: Minimal overhead with no reflection
  • 🎯 Easy to use: Simple subscribe/unsubscribe API
  • 🔒 Memory safe: Prevents duplicate subscriptions
  • 🎮 Unity-friendly: Works seamlessly with Unity projects
  • 📦 No dependencies: Pure C# implementation

Installation

Manual Installation

  1. Download the src folder
  2. Copy it to your Unity project's Scripts folder or your C# project

Quick Start

Basic Usage with Arguments

using System;

// Define your event argument class
public class PlayerHealthArgs
{
    public int CurrentHealth { get; set; }
    public int MaxHealth { get; set; }
}

// Create an event
public class GameManager
{
    public GameEvent<PlayerHealthArgs> OnPlayerHealthChanged = new();
    
    public void TakeDamage(int damage)
    {
        // Your damage logic here
        
        // Raise the event
        OnPlayerHealthChanged.Raise(new PlayerHealthArgs 
        { 
            CurrentHealth = 75, 
            MaxHealth = 100 
        });
    }
}

// Subscribe to the event
public class UIHealthBar
{
    private GameManager _gameManager;
    
    void Start()
    {
        _gameManager = FindObjectOfType<GameManager>();
        _gameManager.OnPlayerHealthChanged.Subscribe(OnHealthChanged);
    }
    
    void OnHealthChanged(PlayerHealthArgs args)
    {
        Debug.Log($"Health: {args.CurrentHealth}/{args.MaxHealth}");
        // Update your UI here
    }
    
    void OnDestroy()
    {
        // Don't forget to unsubscribe!
        _gameManager.OnPlayerHealthChanged.Unsubscribe(OnHealthChanged);
    }
}

Events Without Arguments

// For simple events without data
public class GameManager
{
    public GameEventNoArgs OnGameStart = new();
    public GameEventNoArgs OnGameOver = new();
    
    public void StartGame()
    {
        OnGameStart.Raise();
    }
}

public class AudioManager
{
    void Start()
    {
        var gameManager = FindObjectOfType<GameManager>();
        gameManager.OnGameStart.Subscribe(PlayGameStartMusic);
    }
    
    void PlayGameStartMusic()
    {
        // Play music
    }
}

Advanced Examples

Multiple Subscribers

public class ScoreArgs
{
    public int Score { get; set; }
    public int Combo { get; set; }
}

public GameEvent<ScoreArgs> OnScoreChanged = new();

// Multiple systems can subscribe to the same event
uiManager.OnScoreChanged.Subscribe(UpdateScoreUI);
achievementManager.OnScoreChanged.Subscribe(CheckAchievements);
audioManager.OnScoreChanged.Subscribe(PlayScoreSound);

Singleton Pattern Integration

public class EventManager : MonoBehaviour
{
    public static EventManager Instance { get; private set; }
    
    public GameEvent<PlayerHealthArgs> OnPlayerHealthChanged = new();
    public GameEvent<ScoreArgs> OnScoreChanged = new();
    public GameEventNoArgs OnLevelComplete = new();
    
    void Awake()
    {
        if (Instance == null)
        {
            Instance = this;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            Destroy(gameObject);
        }
    }
}

// Usage from anywhere
EventManager.Instance.OnPlayerHealthChanged.Subscribe(HandleHealthChange);

API Reference

GameEvent<T>

Method Description
Subscribe(Action<T> listener) Subscribe a method to the event. Prevents duplicate subscriptions.
Unsubscribe(Action<T> listener) Unsubscribe a method from the event.
Raise(T args) Invoke all subscribed methods with the provided arguments.

GameEventNoArgs

Method Description
Subscribe(Action listener) Subscribe a method to the event. Prevents duplicate subscriptions.
Unsubscribe(Action listener) Unsubscribe a method from the event.
Raise() Invoke all subscribed methods.

Best Practices

✅ Do's

// Always unsubscribe in OnDestroy/Dispose
void OnDestroy()
{
    eventManager.OnPlayerDeath.Unsubscribe(HandlePlayerDeath);
}

// Use meaningful event argument classes
public class DamageArgs
{
    public int Damage { get; set; }
    public GameObject Attacker { get; set; }
    public DamageType Type { get; set; }
}

// Keep event handlers focused and simple
void OnPlayerDamaged(DamageArgs args)
{
    UpdateHealthBar(args.Damage);
}

❌ Don'ts

// Don't forget to unsubscribe (causes memory leaks!)
void OnDestroy()
{
    // Missing unsubscribe!
}

// Don't use complex logic in event handlers
void OnPlayerDamaged(DamageArgs args)
{
    // Too much logic here!
    CalculateDamage();
    UpdateUI();
    PlaySound();
    CheckAchievements();
    // Better to split this up
}

// Don't subscribe in Update or frequently called methods
void Update()
{
    // ❌ Creates multiple subscriptions!
    eventManager.OnScoreChanged.Subscribe(HandleScore);
}

Performance Considerations

  • Event invocation is O(n) where n is the number of subscribers
  • Subscription/unsubscription is O(n) due to list operations
  • Minimal memory overhead (one List per event)
  • No boxing/unboxing or reflection
  • Thread-safe: No (use locks if calling from multiple threads)

Comparison with Alternatives

Feature GameEvent UnityEvent C# event
Type-safe
Editor visible
Serializable
Performance ⚡⚡⚡ ⚡⚡⚡
Easy unsubscribe ⚠️
Prevents duplicates N/A

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Support

If you find this useful, please consider:

  • ⭐ Starring the repository
  • 🐛 Reporting bugs
  • 💡 Suggesting new features

Credits

Created for the Unity and C# developer community.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages