Lightweight messaging in Unity with TinyMessenger

Up until a few days ago I had been working on a yet-to-be-announced iOS game made with the Unity game engine, and I believe that one of the best technical decisions I had made in designing it was to use an in-process messaging system from the get-go. That decision continued to pay dividends until the very end as it helped keep the various components in the game well-separated and as self-contained as possible, which led to a code base that is more maintainable and resilient to change as it grew.

There are several messaging systems out there that are specifically built for the Unity game engine, but I decided to go with a more general purpose solution from a little gem of an open source library called TinyIoC.

TinyIoC is an elegant Inversion of Control library that is tiny enough (Ha!) to fit into a single C# source file, and it would definitely be on the top of my list if I were going to add some IoC to any project. But it also comes bundled with a tiny (Ha!) messaging system system called TinyMessenger, which has several advantages over the Unity-specific solutions out there, mainly because:

  • It doesn’t use magic strings
    Most of the Unity-specific messaging systems use strings to identify message types. And those are ugly, prone to errors, and redundant since the type of a message object is enough to identify the message.
  • It’s being actively maintained
    And by people who are definitely much smarter than me, as evident from the project’s GitHub repository. The main repo isn’t seeing much action as of late, but the number of forks and pull requests is enough reassurance for me.
  • Its licensing terms are clear
    The Ms-PL might not be everyone’s cup of tea, but it suits me just fine.

Plus it just feels more C#-like than any of the Unity-specific solutions I’ve seen so far.

Setting Up TinyMessenger with Unity

Using TinyMessenger with Unity is simple. Start by grabbing the file TinyMessenger.cs from the GitHub repo and place it somewhere in your project’s Assets folder. It’s probably best to place it in a folder called “Plugins” to ensure that it is compiled before regular scripts.

Then read through the documentation, the gist of which is that you’ll need to create an instance of the TinyMessengerHub class, derive your message types from TinyMessageBase, and use the hub’s Publish and Subscribe methods for communication.

I didn’t use TinyMessengerHub directly. But instead I made a class called “MessageHub” that derives from MonoBehaviour and that creates a single instance of TinyMessengerHub in a way that plays nice with the Unity runtime. Here it is in all its gory details:

Just copy the code above into a file in your Assets folder or download the gist. It will automatically create a GaemObject in your scenes called “MessageHub” when needed. Tweak it to taste.

Usage Example

The game I mentioned above has enemies, and those enemies can be killed by the player, and several things need to happen when they die:

  • An EnemiesController component must keep a tally of how many instances of each enemy type are on stage so it can decide what kind of enemies to spawn and at what rate.
  • A ScoreKepper component calculates the player’s score based on the number of killed enemies, how quickly they were killed, and whether the kill was part of a combo.
  • Etc, etc.

To communicate this major event to other components in the system, we start by defining a message class named EnemyDiedMessage:

In this particular example, all enemies share a base class called EnemyControllerBase (which is far less confusing than the original name I had for it, EnemyBaseController).

In the EnemyControllerBase class, the message is sent to the MessageHub when an enemy dies:

Any other component that wishes to receive this message needs to subscribe to it like so:

And that’s all there is to it. I have tested this setup with Unity 4.0.1 and 4.2.1 on PC, iOS and Windows Phone 8 and I didn’t come across any issues. The performance overhead is also nonexistent if the Unity profiler is to be believed.

Leave a Reply