Skip to content

A typesafe, lightweight Unity message bus system that respects the Open-Closed principle.

License

Notifications You must be signed in to change notification settings

JoanStinson/UnityMessagingSystem

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

22 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Unity Messaging System

A typesafe, lightweight Unity message bus system that respects the Open-Closed principle.

Made With Unity License Last Commit Repo Size Downloads Last Release


📣 How It Works

For starters, import the package located in the Releases section into your project.

  • Step 1 - Write a message. It can be a class or a struct.

public readonly struct PlayerSpawnMessage
{
    public readonly int Health;
    public readonly float Speed;
}

Structs are preferred to reduce GC work and because messages will 99% of the time only contain data.

If the message doesn't require data, you can have an empty class or struct too.

public readonly struct PlayerDeathMessage { }
  • Step 2 - Inherit from IMessagingSubscriber<> explicitly defining the message type and subscribe to it.

    public class MessagingSubscriberExample : MonoBehaviour,
        IMessagingSubscriber<PlayerSpawnMessage>,
        IMessagingSubscriber<PlayerDeathMessage>
    {
        private void OnEnable()
        {
            MessagingSystem.Instance.Subscribe<PlayerSpawnMessage>(this);
            MessagingSystem.Instance.Subscribe<PlayerDeathMessage>(this);
        }

        private void OnDisable()
        {
            MessagingSystem.Instance.Unsubscribe<PlayerSpawnMessage>(this);
            MessagingSystem.Instance.Unsubscribe<PlayerDeathMessage>(this);
        }

        public void OnReceiveMessage(PlayerSpawnMessage message)
        {
            Debug.Log(message.ToString());
        }

        public void OnReceiveMessage(PlayerDeathMessage message)
        {
            Debug.Log("Received Player Death message");
        }
    }

You can make use of the DefaultMessagingSystem singleton via the Instance property. Nevertheless, I prefer to inject the dependency, so that later on I can mock it and do unit tests, apart from having a different messaging system implementation if it where required.

  • Step 3 - Create a message instance and dispatch it.

public class ExampleDispatcherClass : MonoBehaviour
{
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            MessagingSystem.Instance.Dispatch(new PlayerSpawnMessage(3, 5));
            MessagingSystem.Instance.Dispatch(new PlayerDeathMessage());
        }
    }
}

The same as I said before, be sure to have the same instance referenced. Either by injecting it via a constructor/initialize method or making use of the singleton Instance (although less recommended for obvious reasons, unless you are a beginner).

🔍 Unit Tests

Unit tested with 100% code coverage to be certain the messaging system implementation works properly.