Refactor event management: remove old EventManager and EventExample scripts, add new Core/EventManager as singleton

This commit is contained in:
Will Stuckey
2025-10-28 13:02:48 -05:00
parent 3deeb42403
commit 873cc7dd17
8 changed files with 81 additions and 198 deletions

View File

@@ -1,96 +0,0 @@
# ConfigurableEventManager Implementation Guide
## What is ConfigurableEventManager?
The ConfigurableEventManager is a Godot Node that provides a visual, inspector-based way to define and manage events in your game without writing code for each event.
## How to Set It Up
### Step 1: Add EventManager to Your Scene
1. Open `Scenes/Main.tscn` in Godot
2. The EventManager node should already be added as a child of Main
3. Select the EventManager node in the scene tree
### Step 2: Create GameEventResource Assets
You need to create `.tres` resource files that define your events:
1. In Godot, right-click in the FileSystem dock → **New Resource**
2. Search for **GameEventResource** and select it
3. Click **Create**
4. Save it in `Resources/Events/` (you may need to create this folder)
Example event resources to create:
#### GameStarted.tres
- **Event Name**: `GameStarted`
- **Description**: `Fired when the game begins`
- **Parameter Count**: `0`
- **Category**: `Game`
#### ScoreChanged.tres
- **Event Name**: `ScoreChanged`
- **Description**: `Fired when player score changes`
- **Parameter Count**: `1`
- **Parameter1 Type**: `int`
- **Parameter1 Description**: `The new score value`
- **Category**: `Player`
#### PlayerLevelUp.tres
- **Event Name**: `PlayerLevelUp`
- **Description**: `Fired when player gains a level`
- **Parameter Count**: `2`
- **Parameter1 Type**: `string`
- **Parameter1 Description**: `Player name`
- **Parameter2 Type**: `int`
- **Parameter2 Description**: `New level number`
- **Category**: `Player`
### Step 3: Configure EventManager in Inspector
1. Select the EventManager node in your scene
2. In the Inspector, find the **Events** array property
3. Click to expand it and set the **Size** to match your number of events (e.g., 3)
4. Drag your `.tres` event resource files into each array slot
5. Optionally enable **Enable Debug Logging** to see event activity in the console
### Step 4: Use Events in Your Scripts
See `Scripts/EventExample.cs` for a complete example of:
- Getting a reference to the EventManager
- Subscribing to events
- Raising events
- Unsubscribing from events
## Key Benefits
**Visual Configuration** - Define events in the Inspector without code
**Type Safety** - Still get compile-time checking in C#
**Documentation** - Event descriptions and parameter info built-in
**Debug Logging** - Optional logging for all event activity
**Validation** - Warns if you subscribe with wrong parameter count
## Usage Pattern
```csharp
// 1. Get reference
_eventManager = GetNode<ConfigurableEventManager>("/root/Main/EventManager");
// 2. Subscribe
_eventManager.Subscribe<int>("ScoreChanged", OnScoreChanged);
// 3. Raise event somewhere
_eventManager.Raise("ScoreChanged", 100);
// 4. Unsubscribe when done
_eventManager.Unsubscribe<int>("ScoreChanged", OnScoreChanged);
```
## Next Steps
1. Open the project in Godot 4.5
2. Create your GameEventResource assets in the editor
3. Add them to the EventManager's Events array
4. Use the example script as a template for your game objects
5. Enable debug logging to see events firing in real-time

View File

@@ -1,8 +1,6 @@
[gd_scene load_steps=1 format=3 uid="uid://bvx8qw3yqn5yk"] [gd_scene load_steps=2 format=3 uid="uid://bvx8qw3yqn5yk"]
[ext_resource type="Script" path="res://Scripts/Main.cs" id="1_1"] [ext_resource type="Script" uid="uid://emch0q5mxf8k" path="res://Scripts/Main.cs" id="1_1"]
[node name="Main" type="Node2D"] [node name="Main" type="Node2D"]
script = ExtResource("1_1") script = ExtResource("1_1")
[node name="EventManager" type="EventManager" parent="."]

View File

@@ -0,0 +1,78 @@
using Godot;
using EinSoftworks.Events;
namespace Voider;
/// <summary>
/// Autoload singleton that provides access to the ConfigurableEventManager
/// </summary>
public partial class EventManager : Node
{
private static EventManager _instance;
public static EventManager Instance => _instance;
private ConfigurableEventManager _eventManager;
public override void _Ready()
{
_instance = this;
_eventManager = new ConfigurableEventManager();
}
/// <summary>
/// Raise a game event using the resource's EventName
/// </summary>
public void RaiseEvent(GameEventResource eventResource)
{
if (eventResource?.EventName != null)
{
_eventManager.Raise(eventResource.EventName);
}
}
/// <summary>
/// Raise a game event by name
/// </summary>
public void RaiseEvent(string eventName)
{
_eventManager.Raise(eventName);
}
/// <summary>
/// Subscribe to a game event using the resource's EventName
/// </summary>
public void Subscribe(GameEventResource eventResource, System.Action callback)
{
if (eventResource?.EventName != null)
{
_eventManager.Subscribe(eventResource.EventName, callback);
}
}
/// <summary>
/// Subscribe to a game event by name
/// </summary>
public void Subscribe(string eventName, System.Action callback)
{
_eventManager.Subscribe(eventName, callback);
}
/// <summary>
/// Unsubscribe from a game event using the resource's EventName
/// </summary>
public void Unsubscribe(GameEventResource eventResource, System.Action callback)
{
if (eventResource?.EventName != null)
{
_eventManager.Unsubscribe(eventResource.EventName, callback);
}
}
/// <summary>
/// Unsubscribe from a game event by name
/// </summary>
public void Unsubscribe(string eventName, System.Action callback)
{
_eventManager.Unsubscribe(eventName, callback);
}
}

View File

@@ -0,0 +1 @@
uid://yt5e67nfdc6y

View File

@@ -1,81 +0,0 @@
using Godot;
using EinSoftworks.Events;
namespace Voider;
/// <summary>
/// Example script demonstrating how to use the ConfigurableEventManager.
/// This would typically be attached to a Player, Enemy, or other game object.
/// </summary>
public partial class EventExample : Node
{
// Reference to the ConfigurableEventManager in the scene
private EventManager _eventManager;
public override void _Ready()
{
// Get reference to the ConfigurableEventManager node
// (Assumes it's named "EventManager" in your scene tree)
_eventManager = GetNode<EventManager>("/root/Main/EventManager");
// Subscribe to events
SubscribeToEvents();
}
private void SubscribeToEvents()
{
// Example: Subscribe to a simple event with no parameters
_eventManager.Subscribe("GameStarted", OnGameStarted);
// Example: Subscribe to an event with one parameter (int score)
_eventManager.Subscribe<int>("ScoreChanged", OnScoreChanged);
// Example: Subscribe to an event with two parameters (string playerName, int level)
_eventManager.Subscribe<string, int>("PlayerLevelUp", OnPlayerLevelUp);
}
// Event handlers
private void OnGameStarted()
{
GD.Print("Game has started!");
}
private void OnScoreChanged(int newScore)
{
GD.Print($"Score changed to: {newScore}");
}
private void OnPlayerLevelUp(string playerName, int newLevel)
{
GD.Print($"{playerName} leveled up to level {newLevel}!");
}
// Example of raising events from code
public void SomeGameAction()
{
// Raise an event with no parameters
_eventManager.Raise("GameStarted");
// Raise an event with one parameter
_eventManager.Raise("ScoreChanged", 100);
// Raise an event with two parameters
_eventManager.Raise("PlayerLevelUp", "Player1", 5);
}
public override void _ExitTree()
{
// Always unsubscribe when node is removed
UnsubscribeFromEvents();
}
private void UnsubscribeFromEvents()
{
if (_eventManager != null)
{
_eventManager.Unsubscribe("GameStarted", OnGameStarted);
_eventManager.Unsubscribe<int>("ScoreChanged", OnScoreChanged);
_eventManager.Unsubscribe<string, int>("PlayerLevelUp", OnPlayerLevelUp);
}
}
}

View File

@@ -1 +0,0 @@
uid://b4fnyaf5ok7hg

View File

@@ -1,15 +0,0 @@
using Godot;
using EinSoftworks.Events;
namespace Voider;
/// <summary>
/// Wrapper for ConfigurableEventManager that makes it available in this project.
/// This inherits from the library's ConfigurableEventManager.
/// </summary>
[GlobalClass]
public partial class EventManager : ConfigurableEventManager
{
// Inherits all functionality from ConfigurableEventManager
// You can add project-specific event manager functionality here if needed
}

View File

@@ -1 +0,0 @@
uid://butot2dkursrs