Refactor event management: remove old EventManager and EventExample scripts, add new Core/EventManager as singleton
This commit is contained in:
@@ -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
|
|
||||||
@@ -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="."]
|
|
||||||
|
|||||||
78
Scripts/Core/EventManager.cs
Normal file
78
Scripts/Core/EventManager.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
1
Scripts/Core/EventManager.cs.uid
Normal file
1
Scripts/Core/EventManager.cs.uid
Normal file
@@ -0,0 +1 @@
|
|||||||
|
uid://yt5e67nfdc6y
|
||||||
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://b4fnyaf5ok7hg
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
uid://butot2dkursrs
|
|
||||||
Reference in New Issue
Block a user