Add ConfigurableEventManager implementation with example and guide

This commit is contained in:
Will Stuckey
2025-10-28 12:31:59 -05:00
parent a1f09a6a3b
commit 33cb8e82d4
4 changed files with 185 additions and 1 deletions

96
EVENTS_GUIDE.md Normal file
View File

@@ -0,0 +1,96 @@
# 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,3 +1,9 @@
[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"]
[node name="Main" type="Node2D"] [node name="Main" type="Node2D"]
script = ExtResource("1_1")
[node name="EventManager" type="Node" parent="."]
script = ExtResource("ConfigurableEventManager")

81
Scripts/EventExample.cs Normal file
View File

@@ -0,0 +1,81 @@
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 ConfigurableEventManager _eventManager;
public override void _Ready()
{
// Get reference to the ConfigurableEventManager node
// (Assumes it's named "EventManager" in your scene tree)
_eventManager = GetNode<ConfigurableEventManager>("/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

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