Spectragate





Fixing common Advanced C# Messenger issues

Category : Tutorials, Unity · by Oct 12th, 2015

In the latest project I’m working on I’m making heavy use of the Advanced C# Messenger. It’s a brilliant script that acts more like a Mediator Pattern than a plain Send/Receive messenger, which is fine with me.

However as great as this plugin is, there are two small issues I ran into pretty quickly.

No Listeners Available

To make ACM (is that an acronym?) work like a true mediator system, it needs to give exactly zero craps about what’s actually listening to the broadcasts. Unfortunately if you try to send of a broadcast and no listeners are setup, you’ll quickly run into this error:

“BroadcastException: Broadcasting message “SaySomething” but no listener found. Try marking message with Messenger.MarkAsPermanent”.

Marking the message as permanent wont solve anything. Luckily ACM comes with a way to fix this: comment out this line at the top of Messenger.cs

This simply disables the check for any listeners before it broadcasts a message. Easy! The documentation on the wikipedia page doesn’t mention it, so unless you connect the dots yourself you’ll go down the wrong path thinking there is an issue with permanent messages, like I did.

Unexpected results when restarting scene in Unity 5.2

This one took me a bit longer to hunt down. You load your scene by pressing the play button in the Unity Editor (so no Application.LoadLevel calls are made) and everything loads and works fine. You then call “Application.LoadLevel” to restart your scene and, no matter how simple your scene is, some messages make it through and others don’t. What the horse?

This bug is because of a breaking change in Unity 5.2: Before Unity 5.2 OnLevelWasLoaded was called before Awake. Now that this has been fixed, any listener events you are setting up in your Awake calls are going to get deleted when OnLevelWasLoaded is called. This is because Messenger.cs automatically calls ‘Clear()’ (which removes all the current listeners) when this event triggers.

The simple fix is to comment out the .Clear (line 304 in Messenger.cs) that happens and call it manually yourself when you are changing scenes.

Unfortunately because OnLevelWasLoaded no longer fires before Awake, there doesn’t seem to be a replacement method yet that can take its place. Perhaps a new OnLevelWasUnloaded method would be a handy?

SHARE :

(1) Comment

Carlos Rubiales Bravo
8 months ago · Reply

Hello!

I was looking for a solution to this same problem (#2), and found your answer. It didn’t feel completely “clean” (I don’t want to remember things… let the computer do it!), so I found a solution for it to be completely automatic:

The solution is simple: make MessengerHelper register for the Unity Event SceneManagement.sceneUnloaded. And THEN, when it happens, perform the Cleanup.

The MessengerHelper would look something like this:

void Awake()
{
DontDestroyOnLoad(gameObject);
SceneManager.sceneUnloaded += SceneManager_sceneUnloaded;
}

private void SceneManager_sceneUnloaded(Scene arg0)
{
//Debug.Log(“Level was unloaded. Cleaning up the event tables!”);
Messenger.Cleanup();
}

Hope it works for you!

Leave a Reply

Your email address will not be published. Required fields are marked *