UnityEvent, where have you been all my life?

Yes. That’s what editor scripting is for. Have a look at property drawers

Great info and a good giggle to boot, thanks Joe! :slight_smile:

This is great to hear about and I’d like to thank JoeStrout for pointing it out. I’ve been using the 4.6 GUI system for awhile with that stuff in the inspector and wondered if there was a way to do the same thing for things that aren’t GUI objects. It looks like this is exactly the thing to do it. So, thanks :slight_smile:

1 Like

So can this system be used in replacement of the previous event system?

So if I have GO1 with script:

using UnityEngine;
using System.Collections;

public class EventManager : MonoBehaviour
{
    public delegate void MyEventDelegate();
    public static event MyEventDelegate myEvent;

    voidStart ()
    {
        if(myEvent != null)
        {
             myEvent();
        }
    }
}

Following with GO2 with script:

using UnityEngine;
using System.Collections;

public class ReactToEvent : MonoBehaviour
{
    void OnEnable()
    {
        EventManager.myEvent += PrintStuff;
    }

    void OnDisable()
    {
        EventManager.myEvent -= PrintStuff;
    }

    void PrintStuff()
    {
        Debug.Log("myEvent received!");
    }
}

What would be equivalent setup and code with this new event system you advocate for?

GO1:

using UnityEngine;
using UnityEngine.Events;

public class EventManager : MonoBehaviour
{
    public UnityEvent myEvent;

    void Start()
    {
        myEvent.Invoke();
    }
}

GO2:

using UnityEngine;

public class ReactToEvent : MonoBehaviour
{

    public void PrintStuff()
    {
        Debug.Log("myEvent received!");
    }
}

Assign ReactToEvent->PrintStuff to GO1’s “My Event” handler in the inspector.

[EDIT: Made PrintStuff public – Thanks, @JoeStrout!]

1 Like

One minor correction: PrintStuff() needs to be public to work with the inspector.

How could you do that assignment in code?

1 Like

UnityEvent.AddListener().

1 Like

So:

EventManager aManager = new EventManager();
aManager.myEvent.AddListener(() => { PrintStuff(); });

Not that I would new a MonoBehavior but I needed some way to show I was getting a reference to it.

1 Like

Is there way to avoid setting the reference in the EventManager? On the original example the EventManager does not need to know what script is subscribing to the event. You just handle it on the receiving end with subscription.

EventManager aManager = new EventManager();
aManager.myEvent.AddListener(() => { PrintStuff(); });

Does it go to GO1 or GO2? If it works on the GO2 side I suppose that is then equivalent of the original old event example.

In your subscribing script, you could reference the public UnityEvent field of the notifying script. Or you could use Unity’s Messaging System, which is probably more along the lines of what you want to do anyway. Love/Hate uses the messaging system fairly extensively to do exactly what you’re describing, and it works well.

Ok, so it was just a misunderstanding on my side. I am quite happy with the original “old” event style what I have been using a bit now. I was just hoping there was an even easier way to create, trigger and receive events :slight_smile:

In any case this topic is super useful. Immediately started using it in my project!

1 Like

Thanks for sharing, @JoeStrout !

1 Like

Wow, that is huge. I had no idea.

EDIT: live training session removed to avoid any confusion.

2 Likes

Thanks for pointing that out. It’s not really about UnityEvents in general, nor about how I would say they are “normally” used, but instead about making a string-based event dispatcher.

The EventManager he’s created here is a listen/subscribe notification system based on string keys. You don’t need UnityEvent to do this; you could use standard C# events just as well. I don’t see any particular advantage to UnityEvent, the way it’s being used here. (Indeed, this is pretty much exactly what many of us have done in the past.)

When you’re doing everything from code, a system like this makes pretty good sense (though I cringe at the use of magic strings as the event keys). It really only makes sense though for “global” events; it wouldn’t be appropriate for between two components on the same game object, or making something react to a particular button, etc. For that, a straight-up public UnityEvent works much better.

But I have been pondering the proper organization for global events. For example, suppose you have a busy world with lots of objects, and the world can experience an earthquake. There are various things that might trigger an earthquake, and lots of different things need to respond to an earthquake.

In this case, you would use a pattern I’ve been calling “event relay.” There would be some global object (let’s call it World in this case), which would act as the relay by having an event (quakeOccurred) for notifying everyone of the earthquake, and also a public method (TriggerQuake) for triggering the earthquake.

So, every object that can somehow trigger an earthquake would invoke TriggerQuake (in response to some internal logic, or as the handler for some other event). And every object that needs to know about a quake simply adds a handler to quakeOccurred.

I guess we can look at it this way: a simple UnityEvent invoked according to some logic represents a 1:Many relationship between the invoking object and the handlers. The Event Relay pattern handles a Many:Many relationship between invokers and handlers.

The EventManager in this presentation handles the same many:many relationship, but relies on magic strings (or other keys), and is set up in code rather than in the inspector. I have mixed feelings about that.

2 Likes

@JoeStrout , Yeah, I just finished watching it and noticed that it’s not exactly the use we want to make of UnityEvents.
I will edit my message and remove the link as it will mostly confuse new comers to UnityEvents.

Sorry… I should of watched it before posting it! :sweat_smile:

I don’t think it’s a presentation to avoid, necessarily. But I do agree that it fails to really show off what makes UnityEvents cool.

I’m half-tempted to make my own video, redoing the same demo, but using UnityEvents in their more natural way. It’d be considerably less code, and safer too. And the little exploding minions certainly are cute. :slight_smile:

4 Likes

I certainly wouldn’t stop you.

@JoeStrout , great idea!