Overview
This recipe shows you how to use theEventDispatcher service to implement decoupled communication between components. You’ll learn how to inject the EventDispatcher, register event handlers, dispatch events from publisher components, and properly clean up subscriptions. This pattern is ideal for cross-system notifications where components shouldn’t have direct references to each other.
Prerequisites
- SDK modules: Molca Core installed
- Unity setup: RuntimeManager configured in your scene
- Prior knowledge: Dependency injection, EventDispatcher
- Recommended: Complete Recipe: Implement dependency injection first
Step-by-step
Step 1: Inject EventDispatcher into components
Use the[Inject] attribute to get the EventDispatcher service in both publisher and subscriber components.
[Inject] attribute tells RuntimeManager to automatically populate the _eventDispatcher field after initialization. This eliminates the need for singleton patterns or manual service lookups.
Step 2: Register event handlers in OnEnable
Subscribe to events inOnEnable using RegisterEvent. Use parameterless registration for simple notifications or generic registration for typed payloads.
OnEnable ensures handlers are active whenever the component is enabled. The RegisterEvent<T> generic method allows type-safe payload delivery without casting.
Step 3: Unregister handlers in OnDisable
Always unregister event handlers inOnDisable to prevent memory leaks and errors when the component is destroyed.
MissingReferenceException errors. The OnEnable/OnDisable pairing ensures proper cleanup across enable/disable cycles.
Step 4: Dispatch events from publisher components
UseDispatchEvent to publish events. Other components registered for that event will receive the notification immediately.
DispatchEvent invokes all registered callbacks for that event name immediately. The generic DispatchEvent<T> version passes the payload to all handlers registered with matching type parameter.
Step 5: Use EventConstants for type-safe event names
Instead of magic strings, useEventConstants or define your own constants class for better maintainability and refactoring support.
Complete example
Here’s a complete example showing a training scenario with multiple components communicating via events:- Multiple subscribers listening to the same event
- Type-safe event names using constants
- Proper registration/unregistration lifecycle
- Decoupled communication (components don’t reference each other)
- Publisher doesn’t know who’s listening
Troubleshooting
- Event not received: Confirm
RegisterEventruns before the firstDispatchEvent. If subscription is inOnEnablebut dispatch fires duringRuntimeManagerinitialization, the handler may not be registered yet. Move subscription toStartwithawait RuntimeManager.WaitForInitialization(). - Duplicate callbacks firing: Calling
RegisterEventtwice with the same callback adds it twice. Always pair withUnregisterEventinOnDisableto prevent stacking across enable/disable cycles. - MissingReferenceException after scene unload: Destroyed objects’ callbacks remain registered. Always call
UnregisterEventinOnDisableorOnDestroy. - Wrong type parameter: The type key must match exactly between publisher and subscriber.
DispatchEvent<int>will not reachRegisterEvent<float>handlers even with the same event name. - Events fire but handler doesn’t execute: Check that the subscriber component is enabled and active. Handlers registered in
OnEnablewon’t fire if the GameObject is disabled.
Related
- EventDispatcher — complete API reference and detailed documentation
- Dependency injection — how to inject EventDispatcher into components
- Recipe: Implement dependency injection — prerequisite recipe for using [Inject]
- RuntimeManager — service container that provides EventDispatcher