Skip to content

Repository files navigation

notification-center

English | 한국어

A lightweight publish/subscribe (observer) message bus for Unity. Broadcast a notification from anywhere and let any number of receivers handle it, without direct references between them.

  • No dependencies, no MonoBehaviour, no scene object required
  • Observers are held by WeakReference, so a destroyed receiver never keeps the bus alive
  • Optional object pooling for Notification instances (NOTIFICATION_USE_POOL)

Requirements

  • Unity 2019.3 or later (required for installing packages via git URL)

Installation

Install via git URL

Edit Packages/manifest.json in your Unity project and add this repository as a dependency:

{
  "dependencies": {
    "com.ez.notification-center": "https://github.com/ez8801/notification-center.git"
  }
}

Or in the Unity Editor: Window > Package Manager > + > Add package from git URL... and paste:

https://github.com/ez8801/notification-center.git

Getting Started

All types live in the Foundation.Notifications namespace.

1. Declare notification names

A NotificationName is implicitly convertible to and from string. Collecting the names in one place avoids typos.

using Foundation.Notifications;

namespace R
{
    public class Id
    {
        public static readonly NotificationName OnHpChanged = nameof(OnHpChanged);
        public static readonly NotificationName OnMpChanged = nameof(OnMpChanged);
    }
}

2. Receive notifications

Implement INotificationReceiver and register the receiver with the notification center.

using UnityEngine;
using UnityEngine.UI;
using Foundation.Notifications;

public class HpBar : MonoBehaviour, INotificationReceiver
{
    [SerializeField]
    private Slider _slider;

    private void Awake()
    {
        // Start receiving OnHpChanged notifications.
        NotificationCenter.Instance.AddObserver(this, R.Id.OnHpChanged);
    }

    public void HandleNotification(Notification notification)
    {
        if (notification.Name == R.Id.OnHpChanged)
        {
            _slider.value = notification.IntExtra / 100f;
        }
    }

    private void OnDestroy()
    {
        NotificationCenter.Instance.RemoveObserver(this, R.Id.OnHpChanged);
    }
}

3. Post notifications

using Foundation.Notifications;

public class Player : MonoBehaviour
{
    public int Hp
    {
        get => _hp;
        set
        {
            _hp = value;

            // Post a notification with a payload.
            NotificationCenter.Post(R.Id.OnHpChanged, _hp);
        }
    }
    private int _hp;

    private void Pause()
    {
        // Post with no payload.
        NotificationCenter.Post("OnPaused");

        // Or build the notification yourself.
        Notification notification = Notification.Create("OnPaused", true);
        NotificationCenter.Post(notification);
    }
}

Posting is synchronous: Post returns after every registered receiver has handled the notification.

Observer Types

Method Behavior
AddObserver(observer, name) Receives every notification posted under name until removed.
AddDisposableObserver(observer, name) Receives name once; all disposable observers of that name are dropped after the post.
AddUniversalObserver(observer) Receives every notification, regardless of name.

API Reference

NotificationCenter

Member Description
NotificationCenter.Instance Lazily created singleton instance.
AddObserver(INotificationReceiver, NotificationName) Register an observer for one notification name. Duplicate registrations are ignored.
AddDisposableObserver(INotificationReceiver, NotificationName) Register a one-shot observer.
AddUniversalObserver(INotificationReceiver) Register an observer for all notifications.
RemoveObserver(INotificationReceiver, NotificationName) Unregister from one notification name.
RemoveObserver(INotificationReceiver) Unregister from all notification names and from the universal list.
RemoveAll() Clear every registered observer.
static Post(Notification) Post a prebuilt notification.
static Post(NotificationName) Post with no payload.
static Post(NotificationName, T) Post with an int, float, long, string, bool, or object payload.

Notification

A notification carries a name plus a fixed set of payload slots. Use the slot matching the type you posted.

Member Description
Name The NotificationName this notification was posted under.
IntExtra int payload. Backed by LongExtra — the two share one slot.
LongExtra long payload.
FloatExtra float payload.
StringExtra string payload.
BoolExtra bool payload.
DataExtra object payload, for anything else.
static Create(...) Create (or reuse, when pooled) a notification with an optional payload.
Clear() Reset the name and every payload slot.

Notes

  • Always unregister. Observers are stored as weak references, so a dead receiver is skipped and pruned on the next post — but a receiver that outlives its usefulness keeps receiving. Pair AddObserver in Awake/Start with RemoveObserver in OnDestroy.
  • RemoveObserver(observer, name) only removes named observers. To detach a universal or disposable observer, use RemoveObserver(observer) or RemoveAll().
  • Not thread-safe. Post and register from the main thread only.
  • Pooling. Notification recycles instances through a finalizer-backed pool (up to 512). Comment out #define NOTIFICATION_USE_POOL at the top of Runtime/Notification.cs to allocate a fresh instance every time. Because pooled instances are reused, do not hold on to a Notification after HandleNotification returns — copy out what you need.

Sample

A runnable Unity project lives in Sample~. It wires a Player that ticks HP/MP to an HpBar, MpBar, and an AbilityButton, all driven entirely by notifications. Open the folder as a Unity project and load Assets/Example/Scenes/ExampleScene.unity.

License

Distributed under the MIT License. See LICENSE for more information.

About

Lightweight publish/subscribe message bus for Unity. No MonoBehaviour, no scene object, weak-referenced observers.

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages