Search Unity

UnityEvent, where have you been all my life?

Discussion in 'Scripting' started by JoeStrout, Apr 24, 2015.

?

Did you know about UnityEvent before this?

  1. No! Thank you! This is so cool!

    35.8%
  2. No, but I still don't see what's the big deal.

    3.1%
  3. Yes, but I didn't realize how cool they were.

    25.6%
  4. Yes, but I still don't see what's the big deal.

    11.2%
  5. Yes, and I use them all the time. Where have you been?!?

    24.4%
  1. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,064
    I just stumbled upon UnityEvent thanks to another thread. I went looking to help someone, but ended up being helped myself, in a big way. In case there's anybody else out there still wandering in a cloud of ignorance, as I was, I thought I'd try to bring it some more attention.

    I may have overlooked it before because the docs (here and here) are rather spartan, not quite up to Unity's usual clear tech-writing standards. But a little experimentation shows they're really easy to use. Say you have a script that occasionally flips a sprite, and you think this flipping is something other scripts might want to know about. Just use UnityEngine.Events at the top of the file, declare a public UnityEvent property, and then call .Invoke() on that property at the appropriate time, like so:

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Events;
    3.  
    4. public class FlipTest : MonoBehaviour {
    5.  
    6.     public UnityEvent flipped;
    7.  
    8.     void Update() {
    9.         if (Input.GetKeyDown(KeyCode.Space)) Flip();
    10.     }
    11.  
    12.     void Flip() {
    13.         transform.localScale = new Vector3(-transform.localScale.x, 1, 1);
    14.         flipped.Invoke();
    15.     }
    16. }
    Now, check out the inspector for this component in your scene:

    Initially that "Flipped ()" list is empty, but I've already smacked the + button twice to hook up two receivers. And, right in the UI, it's pretty amazing — you can invoke almost any method or set any public property (!) of any component of any object in the scene. For example, the first one above changes the name (Behaviour.name) of the main camera to "Foo!". No code required — as soon as this sprite flips, the main camera's name gets changed!

    The second one above is slightly more practical; I had a script called EventLogger, with a method like this:
    Code (CSharp):
    1.     public void Log(string msg) {
    2.         Debug.Log(gameObject.name + ": " + msg);
    3.     }
    As you can see in the inspector screenshot above, it was trivial to not only invoke this method, but specify an argument. So now when the sprite flips, the camera gets renamed and the "It works! Holy crap!" message appears in the Console.

    This is an extremely powerful system for decoupling your classes and components. The sender of the events doesn't have to know anything about the receivers (at least, at the code level). The receivers don't have to know anything about the senders. It doesn't depend on matching things up by name, it doesn't search the hierarchy. In the past I've rolled my own notification systems to accomplish things like this, but now that I know about UnityEvent, it may not be needed.

    If there's anything to not like about UnityEvent, it may be that it's too powerful. It allows the scene editor (who is often a designer, rather than a programmer) to do all sorts of foolish things, like renaming the main camera, which could well break a project. There's certainly enough rope here to shoot yourself in the foot. But I doubt it would often be a problem in pratice. And of course regular old strongly-typed properties are still an option for when hands need to be more tied.

    I've always felt that intercomponent communication was a weakness of Unity's framework design — SendMessage and Broadcast are evil, and using specific-typed properties leads to strong coupling. This is the missing piece that makes the component approach really work, and it deserves more than one cryptic page in the manual and a slim section of the scripting reference. Everybody should be using this, in a large portion of their scripts.

    If this was useful to you, let me know with the poll above... if it's caused a light bulb to go off for even one other person, I'll know my time wasn't wasted!

    Cheers,
    - Joe
     
  2. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    11,983
    I've been wanting a Unity-driven event system for yonks. I use delegates myself but have been meaning to check out Unity's new system, and will do so with whatever project I start next.

    I'd need a "I knew about them and they sound neat, but I haven't checked them out yet." option. ;)
     
    waikit97 and Mycroft like this.
  3. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    11,983
    For the sake of people who don't understand the benefit, amongst other things events:
    1. are a way to allow your objects to communicate with one another without being aware of one another, and
    2. allow you to run code in response to changes, instead of code that checks for changes.
     
    redco37, Issun, elmar1028 and 7 others like this.
  4. rrh

    rrh

    Joined:
    Jul 12, 2012
    Posts:
    331
    I only got into this since January. I love them. It's partly from my background with Flash and AS3, where I used events a lot, and it felt like a step backward when I didn't have a comparable thing in Unity.

    One thing you left out that I love is AddListener()
    http://docs.unity3d.com/ScriptReference/Events.UnityEvent.AddListener.html

    My reason is sometimes it's nice to approach it from the opposite direction like this. An object can invoke an event without needing to know which objects are listening for it.

    For an example I had a game set to music, where I wanted certain things to happen on the beat. So I had a BeatCounter class with a static variable beatEvent and the BeatCounter invoked it according to the timing of the song. And so anything else in the game that I wanted to move to the beat would use BeatCounter.beatEvent.addListener(functionName) to perform an action on the beat.
     
  5. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,125
    UnityEvent <3<3<3<3<3

    I'm writing a cutscene system, and I were creating special wrapper classes for different actions - one for moving a character, one for fading the screen, and so on.

    I realized that each cutscene had me writing at least one special action that would be used just there, and I thought that I should try to make a general system. So I went digging through the UI source to figure out how buttons did their magic, and found the UnityEvent. Holy cow it's powerfull.

    I was kinda considering making this thread myself. Like, the power of just putting this little class here on different gameobjects:

    Code (CSharp):
    1. public class UnityEventWrapper : MonoBehaviour {
    2.  
    3.     public UnityEvent unityEvent;
    4.  
    5.     public void Invoke() {
    6.         unityEvent.Invoke();
    7.     }
    8. }
    Somewhat crazy. I love it! The docs are way too sparse, and this should probably have a tutorial somewhere. It's probably just the engineers at Unity that made this thing and kinda forgot that it was super-awesome at one point along the way.
     
    Ryiah, JoeStrout and der_r like this.
  6. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,470
    What you are doing here was possible before UnityEvent using a even cleaner syntax. Since C# already has events and delegates out of the box. Which works great when it is all done in code very easy to have a class subscribe to a static event.

    What makes UnityEvent great is it provides a way to do this in the inspector on a per object level instead of doing it in the class.

     
    djweinbaum and _met44 like this.
  7. superpig

    superpig

    Quis aedificabit ipsos aedificatores? Unity Technologies

    Joined:
    Jan 16, 2011
    Posts:
    4,167
    Vanilla C# events/delegates cannot be saved into scenes/prefabs, though. So even if you wrote an editor extension to let people plug things into them in the Inspector, you wouldn't be able to use them to actually build up persistent stuff.
     
    NonPlayerCorey, Ryiah, Novack and 2 others like this.
  8. AngryAnt

    AngryAnt

    Keyboard Operator Moderator

    Joined:
    Oct 25, 2005
    Posts:
    3,042
    Aside from what has been mentioned above, another benefit of UnityEvents over C# events and delegates is that they maintain only a weak reference to the subscribers and handle Unity object destruction properly.

    Hence, if a runtime-added listener is destroyed without unregistering with the event, it will still get properly garbage collected and will not receive invokes in a bad state.

    Also, I came across this omission in the API the other day - toss some votes :) http://feedback.unity3d.com/suggestions/unityevent-dot-invoke-at-delay
     
    NonPlayerCorey, Ryiah, Wrymnn and 3 others like this.
  9. timsk

    timsk

    Joined:
    May 27, 2011
    Posts:
    177
    Has anyone done any benchmarks comparing UnityEvents and standard c# delegates/events?

    Just be interested to see the cost of the extra functionality.

    If no one posts benchmarks, I'll knock some out over the weekend and post here.
     
    Ghopper21 likes this.
  10. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,470
    Wow that is a nice feature, since in the case of C# events you have to unsubscribe in OnDisable and null check before invoking.

     
  11. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,616
    There's no option for:

    Yes, but I already wrote my own a year before it was released, and I don't feel like ripping out my existing framework just to use Unity's, especially since it lacks a few features I wrote into my own.
     
  12. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,470
    Ya it looks like the ngui guys had a very similar soultuon before the 4.6 days as well.
     
  13. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,616
    I believe they hired the guy from ngui, and that's where they got it from.
     
  14. der_r

    der_r

    Joined:
    Mar 30, 2014
    Posts:
    259
    Could you elaborate on your cutscene system? I'm working on one myself, but I'm using co-routines for scripting sequences. How are you utilizing the UnityEvents? Thanks! :)
     
  15. AngryAnt

    AngryAnt

    Keyboard Operator Moderator

    Joined:
    Oct 25, 2005
    Posts:
    3,042
    Understandable speculation, but off target :) UnityEvent was in place in a branch well before that guy was briefly hired.

    Why not share with the rest of us the specific feature you'd like added to UnityEvent? :) Well worth cutting down on systems you need to maintain on your own by migrating to equivalents maintained by others, right?
     
  16. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,125

    It's pretty complex at this point. There's a cutscene manager with a custom-build UI. It allows you to add and remove different actions on a timeline. Each action is backed by an object.

    When the cutscene manager starts playing, it keeps a tally of the current time since startup, and kicks off actions as it reaches their starting time.

    So I can place a "move camera to x" event at 3 seconds, drag-and-drop the transform that it's supposed to fly to into a slot in the inspector, tune how fast it's going to move, and then the cutscene manager will make that happen 3 seconds after the cutscene starts playing.

    I'm using the UnityEvents for generic events - essentially, an event in the cutscene system that wraps a UnityEvent, and fires it at it's starting point. So if I have a canon somewhere, and want a cutscene to fire that canon, I'll just create a generic event at that point, drag-and-drop the canon into the UnityEvent's inspector, and have the event set off the Fire() function.

    If I didn't have UnityEvent, I would have to create a subclass of the cutscene's event class that fired canons, and was only used in that cutscene.
     
    Ghopper21 and der_r like this.
  17. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    6,616
    Not when the cost of migrating is higher than maintaining my own. Or the cost of waiting for a fix to something that is of low priority to unity.

    And the features are very personalized. It's primarily a hook into a system of interfaces that I use regularly that are independent of unity as well, and integrating it into UnityEvent would be meaningless to any other user unless they were using my framework.

    Nevermind adding on that fact that the 'unity way' is often in conflict with my own way. I probably won't be sticking with unity much longer, but being as deep as we are with development at this point... we can't leave it quite yet. Of course Unity5 seems to be changing a lot of habits that erk me about unity, only time will tell if they commit to it fully. Deprecating old habits can be difficult when they are well established within your community of users.
     
    Last edited: Apr 24, 2015
  18. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,452
    To be fair these events were only introduced in 4.6. So you aren't too far behind the ball on picking them up. I've been saying since the beta came out that the inclusion of the event system was more significant then the new UI tools. But no one at Unity was making a big deal about it.

    There are some other new powerful features to, including the ExecuteEvents class, that works in the other direction, allowing you to invoke methods on other scripts in a clean fashion. Knocks SendMessage out of the park.

    The EventSystem component is also very powerful, enabling all sorts of magic input stuff to just happen.
     
    Ryiah, JoeStrout and lordofduct like this.
  19. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,470
    @BoredMormon ya I really have to agree with you, UnityEvent and UnityAction were not hyped much on release and kinda views as a tool for the ui system. When they are a more important feature and are useful all over unity.
     
  20. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,064
    Exactly — I'd heard something about them, but it was in the context of the new UI system, but since I was pretty happy with the old UI system, I didn't pay much attention. (I have switched to the new UI system in a new project, but will probably continue to use the old one for a long time in large existing projects.)

    But yeah, UnityEvent is way more useful than just UI. It's the decoupler the whole framework has been lacking. Like some others here, I've been using my own C# events and delegates, and that's fine in code, but has the disadvantages mentioned above in this thread. Then I have my own broadcast/notification system too, which again is fine... but I'm always thinking about how to teach Unity to newbies, and how to make simple, self-contained components that are truly stand-alone, that people can just drop in and use without dragging in some big framework of support classes.

    Both of those considerations make me excited to start using UnityEvent. Basically any component that does or detects something can expose a UnityEvent, enabling other components to react to this however they want. Users can hook it up in the editor, or in code, and they don't need any other framework, they don't need to unregister when destroyed, etc. It just works.

    In our internal framework we've got components that send an announcement (our equivalent of UnityEvent) when they collide with something, when various Inputs are detected, when damage is dealt or received, etc. And then we have other components that react to announcements by showing/hiding/destroying the object, spawning some other prefab, sending another announcement after some configurable delay, moving or rotating the object, etc.

    A library of about 20 components or so allowed my son to build this Hackenslash game with almost no custom code.

    Now I'm picturing rebuilding these components around UnityEvent, and they will be even simpler, because you don't have to code things to "react to an event" — you just have public methods that cause them to do whatever they do, and the user can hook these up to whatever events they like. And we can all share & swap such components without worrying about needing any support system; everything we need is now built in.

    Brilliant!
     
    Ryiah likes this.
  21. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,470
    Ya @JoeStrout in respect to your sons hack n slash game, it reminds me of working with goldsrc engine and worldcraft(old hammer) before I could code. I was able to create new gamemodes just using the maps IO system provided in the editor on entities. This IO system is really just a UI to choose receivers for events.

    Really if you use UnityEvent and create a few logic and trigger components you can get a lot done with no code. At work I plan on making a large library of logic and trigger components for envirmeant artists to add logic to scene with out code.
     
    JoeStrout likes this.
  22. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,064
    I'm thinking the same. Perhaps we should collaborate? The community could come together and make a large collection of simple, one-task components that you can snap together via UnityEvents to make a game without code.

    For example: at the school where I've been volunteering, one of the kids has been working for the last week on a "flappy bird" style game (except instead of a bird it's a cube; he calls it "flappy cube"). He's got physics turned on, and has a script that moves the block forward at a constant velocity, and when the spacebar is pressed, applies a 500-newton upward force. Nothing happens yet when you collide with obstacles but he has ideas of making that trigger a game-over state.

    OK, so how would you build this out of events and components? I'm thinking something like:
    • ConstantSpeed: lets you specify a velocity vector and which axes to apply to; smart enough to work with or without a Rigidbody.
    • InputTrigger: lets you specify an input type (e.g. KeyDown) and input (e.g. KeyCode.Space), and invokes an event.
    • ApplyForce: specify a force vector and duration; public Apply method adds that amount of force over that many seconds.
    • CollisionTrigger: specify the collision mask; invokes an event.
    • PlaySound: actually may not need to make this; I think an AudioSource can probably be triggered by an event already!
    So there you'd go: use ConstantSpeed on the X axis to get the continuous forward motion; InputTrigger set to invoke the ApplyForce to get the upward push whenever you hit the spacebar, and also play a flapping sound; and CollisionTrigger to detect hitting obstacles and do whatever you want — disable the ConstantSpeed component and play a death sound for example.

    Jeez, as a teacher, this gets me excited — not only would kids get very rapid success snapping these games together like Legos, but when they want to peek under the hood, each of these components is going to be short and easily understood.

    Maybe I should start a new thread over in the teaching forum... though such a library wouldn't be just for teaching; as you said, it'd be great for environment artists too.
     
    Ryiah likes this.
  23. timsk

    timsk

    Joined:
    May 27, 2011
    Posts:
    177
    You can basically already do that with playmaker. Or other "visual scripting" packages.
     
  24. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,064
    Yep. But that's not how I'm interested in doing it. (I can elaborate on the reasons if you like, but I feel like it'd be repeating much of my previous post.)
     
  25. Schneider21

    Schneider21

    Joined:
    Feb 6, 2014
    Posts:
    2,886
    This is all new to me, and I'm now very excited to go try it out. Thanks for bringing it to my attention, @JoeStrout!
     
    JoeStrout likes this.
  26. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,470
    @JoeStrout ya those to start but also some pure logic components, like logic case which would be like a switch statement, and logic relay which can be used to fire off a bunch of events at once when triggered or in sequence with timers. Also maybe a basic math component as well. A component that can make descions based on tags as well would be great.

    Also a modified inspector preview window that can display what is subscribed to a component so you see at a glance what triggers a component and what they component triggers.
     
  27. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,064
    Those logic components are a very interesting idea. I'm going to have to give that some more thought.

    As for the inspector preview, I'm not quite sure I follow you. The UnityEvent inspector already shows you what is subscribed (i.e. all receivers). Did you mean the other way — some way to see what events a method is currently set up to be invoked by?
     
  28. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,470
    Yes exactly, be nice at a glance to see what it invokes and what can invoke it.
     
  29. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,527
  30. Vectrex

    Vectrex

    Joined:
    Oct 31, 2009
    Posts:
    204
    I'd really like another inspector UI for the OTHER way round also. ie Listeners subscribing themselves (in addition to the current UnityEvent of the invoker having the listener references)
    I'm thinking the same little + button (maybe next to the help icon on components, or part of the cog icon, "Add listener").
    This would then add similar UI blocks at the bottom. You'd then drag in a GO containing a UnityEvent, select the specific component and actual event. Then you'd finally select the function/property from the current Component, much like you do now (without the component selection)
    NOW you'd be able to click together a properly decoupled game without code.

    ps Supporting static events by dragging in RAW C# CODE or PREFABS would rule. Or just displaying them anyway regardless of any actual use in the instances.
    pps It seems UnityEvent doesn't display all properties and functions. Why not? eg Transform's Rotate function.
    ppps Why can't I add custom parameters without defining a whole new class? This seems messy to me. I expected to be able to do something like
    public UnityEvent<int> OnEventWithInt;
    I guess you can't do that in C#?
     
  31. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,452
    With reflection and a custom inspector you can do pretty much whatever you want.
     
  32. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,064
    Yeah, but @Vectrex is right, UnityEvent and the built-in editor aren't quite as powerful as one would like. But it's (almost) the first release; perhaps we'll see more development of it in future releases.

    Personally, I'd be happier now if there were some easy way to select the current object as the recipient of the event. Instead I have to go find it in the Hierarchy list, or use the object browser — this feels like unnecessary work when I'm already inspecting the object I want to select!

    They probably didn't imagine that this would be common, but I'm finding it so, even with UI things like Button. For example, I have a scene switcher component with a public Load(sceneName as String) method. When I have a scene selection menu or a Back button, I simply throw this component onto each button, and invoke it via the button event. This makes my buttons fully self-contained, so I can copy one and paste it into another scene for example.

    Does anybody know a shortcut I'm missing for assigning an object reference to itself in the editor?
     
  33. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,527
    Can't you just drag that component into the field?
     
  34. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,064
    Drag it by what? I can't find any place on a component that's draggable. Nor can I find anything draggable at the top of the inspector that would represent the whole object (though this wouldn't be very convenient anyway, since often I'd have to scroll to reach the top, then scroll back down to reach the field I'm trying to fill in).
     
  35. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,527
    I usually just drag the component name into the field:
     
    Shushustorm likes this.
  36. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,396
    I think the most important thing to add is clearer documentation. As it stands you have little choice but to learn about UnityEvent by trial and error, or forum posts by this one. And I'm not even certain of the extent of its capabilities (on account of this documentation dearth), so it's hard to make further feature requests without that.

    However, I can make one: The ability to call static functions. The interface for this might be tricky to create without being overly cumbersome, but it'd be well worth the trouble. We could bypass OP's EventLogger script and call Debug.Log directly. We could make our level's enemy call functions for the Player object, or the UI, even if those things are in different scenes until the game is running.
     
    lermy3d, Senshi and jwinn like this.
  37. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    4,125
    The static thing could be solved by allowing you to drag and drop the script into the object field. As of now, you can do that, but the only thing you get available is the script's name.

    By the way, this means that you can have buttons in your game change the name of your scripts. THIS IS PROBABLY NOT A GOOD IDEA.

    EDIT: just checked, it doesn't actually work. Which is probably a good thing.
     
    Senshi and StarManta like this.
  38. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,064
    Well I'll be dipped in spaghetti. It works! I had no idea you could drag the component name; I was always trying to grab the icon instead. This is a serious time-saver!

    Tony, you da man. If we ever bump into each other, I'll buy you a beverage of your choice!
     
    Senshi, idurvesh and TonyLi like this.
  39. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    6,396
    Well, there it is. Interface problem solved.
     
    Senshi likes this.
  40. Vectrex

    Vectrex

    Joined:
    Oct 31, 2009
    Posts:
    204
    That doesn't help with messy extra components cluttering up the place. I actually do that now with C# events using the component "ZZSignalSlot" on the asset store. I had to bug fix it, but it works nicely. But the extra components in the inspector get really messy and hard to keep track of things, so an integrated solution is always going to be better.

    Hmm, can we ADD our own inspector UI stuff to ANY component?
     
  41. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,452
    Yes. That's what editor scripting is for. Have a look at property drawers
     
  42. krougeau

    krougeau

    Joined:
    Jul 1, 2012
    Posts:
    449
    Great info and a good giggle to boot, thanks Joe! :)
     
  43. Todd-Wasson

    Todd-Wasson

    Joined:
    Aug 7, 2014
    Posts:
    1,062
    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 :)
     
    JoeStrout likes this.
  44. Cromfeli

    Cromfeli

    Joined:
    Oct 30, 2014
    Posts:
    188
    So can this system be used in replacement of the previous event system?

    So if I have GO1 with script:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class EventManager : MonoBehaviour
    5. {
    6.     public delegate void MyEventDelegate();
    7.     public static event MyEventDelegate myEvent;
    8.  
    9.     voidStart ()
    10.     {
    11.         if(myEvent != null)
    12.         {
    13.              myEvent();
    14.         }
    15.     }
    16. }
    Following with GO2 with script:
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class ReactToEvent : MonoBehaviour
    5. {
    6.     void OnEnable()
    7.     {
    8.         EventManager.myEvent += PrintStuff;
    9.     }
    10.  
    11.     void OnDisable()
    12.     {
    13.         EventManager.myEvent -= PrintStuff;
    14.     }
    15.  
    16.     void PrintStuff()
    17.     {
    18.         Debug.Log("myEvent received!");
    19.     }
    20. }
    What would be equivalent setup and code with this new event system you advocate for?
     
  45. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,527
    GO1:
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Events;
    3.  
    4. public class EventManager : MonoBehaviour
    5. {
    6.     public UnityEvent myEvent;
    7.  
    8.     void Start()
    9.     {
    10.         myEvent.Invoke();
    11.     }
    12. }
    GO2:
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class ReactToEvent : MonoBehaviour
    4. {
    5.  
    6.     public void PrintStuff()
    7.     {
    8.         Debug.Log("myEvent received!");
    9.     }
    10. }
    Assign ReactToEvent->PrintStuff to GO1's "My Event" handler in the inspector.

    [EDIT: Made PrintStuff public -- Thanks, @JoeStrout!]
     
    Last edited: Apr 30, 2015
    JoeStrout likes this.
  46. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    8,064
    One minor correction: PrintStuff() needs to be public to work with the inspector.
     
  47. Ramcat

    Ramcat

    Joined:
    Aug 16, 2014
    Posts:
    92
    How could you do that assignment in code?
     
    TokyoWarfareProject likes this.
  48. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    9,527
    Ramcat likes this.
  49. Ramcat

    Ramcat

    Joined:
    Aug 16, 2014
    Posts:
    92
    So:
    Code (CSharp):
    1.  
    2. EventManager aManager = new EventManager();
    3. aManager.myEvent.AddListener(() => { PrintStuff(); });
    4.  
    Not that I would new a MonoBehavior but I needed some way to show I was getting a reference to it.
     
    TokyoWarfareProject likes this.
  50. Cromfeli

    Cromfeli

    Joined:
    Oct 30, 2014
    Posts:
    188
    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.

    Code (CSharp):
    1.  
    2. EventManager aManager = new EventManager();
    3. aManager.myEvent.AddListener(() => { PrintStuff(); });
    4.  
    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.
     
    Last edited: May 4, 2015