A flexible and decoupled event system for Unity using ScriptableObjects. Simplify communication between different parts of your game without direct references.
- Overview
- Features
- Getting Started
- Usage Examples
- Supported Event Types
- Creating Custom Event Types
- Demo
- License
UnityConnectChannel implements the publish-subscribe pattern using ScriptableObject-based event channels. This enables the seamless decoupling of systems in your Unity project. Rather than maintaining direct references between components, publishers raise events on Event Channels (ScriptableObjects) while subscribers capture these events through Event Listeners (MonoBehaviours). This architecture eliminates tight coupling, resulting in more modular and maintainable code that's easier to test and more resilient to changes.
- Decoupled Communication: Eliminate direct dependencies between GameObjects and systems.
- ScriptableObject Based: Events are assets, making them easy to manage and reference.
- Type-Safe Events: Built-in support for common data types (Void, Int, String, Bool) and easy extension for custom types.
- Inspector Friendly: Configure listeners and responses directly in the Unity Inspector.
- Conditional Event Raising: Trigger events only when specific conditions are met.
- Debug Capabilities: Optional logging for event raising and listener registration.
- Thread Safety: Designed with thread safety in mind for listener management.
- Recursive Event Protection: Prevents stack overflows from recursive event loops.
- GUID-based Identification: Unique IDs for channels for easier tracking.
You have a couple of options to install UnityConnectChannel into your Unity project:
Option 1: Downloading a .unitypackage
from Releases (Recommended)
- Go to the Releases Page of this repository.
- Download the
UnityConnectChannel-vx.x.x.unitypackage
file (wherex.x.x
is the version number) from the latest (or desired) release. - Open your Unity project.
- Drag and drop the downloaded
.unitypackage
file into your Project window, or go toAssets > Import Package > Custom Package...
and select the file. - Click "Import" in the dialog that appears. All necessary files from the
DevToolKit
folder will be imported into yourAssets
directory.
Option 2: Manual Installation (from source)
- Download or clone this repository.
- Navigate to the
Assets/DevToolKit
folder within the cloned/downloaded repository. - Copy this
DevToolKit
folder into your Unity project'sAssets
folder.
-
Create an Event Channel:
- Right-click in the Project view within your Unity Editor.
- Select
Create > Events > [Type]EventChannel
(e.g.,StringEventChannel
). - Name your newly created Event Channel asset (e.g.,
PlayerNameChangedChannel
).
-
Setup a Publisher (a script that will raise the event):
using DevToolKit.EventChannel.Channels; using UnityEngine; public class PlayerManager : MonoBehaviour { [SerializeField] private StringEventChannel playerNameChannel; public void ChangePlayerName(string newName) { if (playerNameChannel != null) { playerNameChannel.Raise(newName); } else { Debug.LogWarning("PlayerNameChannel is not assigned in the PlayerManager."); } } }
-
Setup a Listener (a component that will react to the event):
- Select a GameObject in your scene.
- In the Inspector, click "Add Component" and search for the corresponding listener type (e.g.,
StringEventListener
). - Drag your created
PlayerNameChangedChannel
asset from the Project view to the "Event Channel" field on theStringEventListener
component. - In the "Unity Event Response" section of the listener, click the "+" button to add a new response.
- Drag the GameObject containing the script with the method you want to call into the object field.
- From the function dropdown, select the public method you want to execute when the event is raised (e.g., a UI update method that takes a string).
// Make sure to assign these channels in the Inspector!
// For VoidEventChannel (no data)
[SerializeField] private VoidEventChannel gameStartChannel;
public void StartGame()
{
if (gameStartChannel != null) gameStartChannel.Raise();
}
// For IntEventChannel
[SerializeField] private IntEventChannel scoreChannel;
public void UpdateScore(int newScore)
{
if (scoreChannel != null) scoreChannel.Raise(newScore);
}
// For conditional raising (example with BoolEventChannel)
[SerializeField] private BoolEventChannel achievementUnlockedChannel;
public void CheckAndUnlockAchievement(int playerScore)
{
if (achievementUnlockedChannel != null)
{
// Raise the event with 'true' (achievement unlocked) if score > 1000
// The first parameter to RaiseIf is the value to pass if the condition is true.
// For a BoolEventChannel, if the condition is met, it will raise 'true'.
achievementUnlockedChannel.RaiseIf(true, val => playerScore > 1000);
}
}
The event listener component (VoidEventListener
, IntEventListener
, StringEventListener
, BoolEventListener
, or your custom listeners) handles the subscription. You just need to:
- Add the appropriate listener component to your GameObject.
- Assign your Event Channel asset to its "Event Channel" field.
- Configure the UnityEvent response in the Inspector by linking it to a public method.
// Example for a UIController responding to score updates
// This script would be on a GameObject, and the UpdateScoreDisplay method
// would be linked to an IntEventListener's UnityEvent.
using UnityEngine;
// Using Unity's built-in UI Text for this example, as per user's previous update.
using UnityEngine.UI;
public class UIController : MonoBehaviour
{
[SerializeField] private Text scoreText; // Standard UI Text
// This method will be connected in the Inspector
// to an IntEventListener's "Unity Event Response"
public void UpdateScoreDisplay(int score)
{
if (scoreText != null)
{
scoreText.text = $"Score: {score}";
}
}
}
UnityConnectChannel includes these pre-configured event channels and listeners:
- Void: For events that don't carry data (
VoidEventChannel
/VoidEventListener
) - Int: For integer data (
IntEventChannel
/IntEventListener
) - String: For string data (
StringEventChannel
/StringEventListener
) - Bool: For boolean data (
BoolEventChannel
/BoolEventListener
)
Each type also has a corresponding Unity event class for inspector use:
UnityVoidEvent
,UnityIntEvent
,UnityStringEvent
,UnityBoolEvent
Extend the system with your own data types in four easy steps:
-
Define your custom data type:
[System.Serializable] public class CustomType { public int id; public string name; }
-
Create a custom event channel:
using DevToolKit.EventChannel.Core.Abstractions; using UnityEngine; [CreateAssetMenu(fileName = "NewCustomTypeEventChannel", menuName = "Events/CustomTypeEventChannel")] public class CustomTypeEventChannel : EventChannelBase<CustomType> { }
-
Create a custom event listener:
using DevToolKit.EventChannel.Core.Abstractions; public class CustomTypeEventListener : EventListener<CustomType, CustomTypeEventChannel> { }
-
Create a custom UnityEvent:
using UnityEngine.Events; [System.Serializable] public class UnityCustomTypeEvent : UnityEvent<CustomType> { }
The included demo scene (Assets/DevToolKit/Demos/DemoScene.unity
) demonstrates:
- Multiple event types (void, int, string, bool, custom)
- UI interaction with the event system (using standard Unity UI Text components).
- Custom type event communication.
- Debug logging capabilities.
The DemoScript.cs
and UIManager.cs
files in Assets/DevToolKit/Demos/Scripts/
provide practical examples of publishing and subscribing to events.
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by CodeTeaBooker