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!

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

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

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

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

    22.4%
  1. TonyLi

    TonyLi

    Joined:
    Apr 10, 2012
    Posts:
    12,694
    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.
     
  2. Cromfeli

    Cromfeli

    Joined:
    Oct 30, 2014
    Posts:
    202
    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 :)

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

    sluice

    Joined:
    Jan 31, 2014
    Posts:
    416
    JoeStrout likes this.
  4. Steve-Tack

    Steve-Tack

    Joined:
    Mar 12, 2013
    Posts:
    1,240
    Wow, that is huge. I had no idea.
     
  5. sluice

    sluice

    Joined:
    Jan 31, 2014
    Posts:
    416
    EDIT: live training session removed to avoid any confusion.
     
    Last edited: May 8, 2015
    metroidsnes and JoeStrout like this.
  6. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    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.
     
    Ryiah and eses like this.
  7. sluice

    sluice

    Joined:
    Jan 31, 2014
    Posts:
    416
    @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! :oops:
     
  8. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    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. :)
     
    sluice, Ryiah, Cromfeli and 1 other person like this.
  9. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    I certainly wouldn't stop you.
     
  10. sluice

    sluice

    Joined:
    Jan 31, 2014
    Posts:
    416
  11. Cromfeli

    Cromfeli

    Joined:
    Oct 30, 2014
    Posts:
    202
    This is what I was searching for :)
     
    JoeStrout likes this.
  12. idurvesh

    idurvesh

    Joined:
    Jun 9, 2014
    Posts:
    495
    Thanks @JoeStrout for spotting more light on UnityEvents, I have been avoiding it since Unity 4.6 come along, but today reading your thread made me reverse my mind and start using it.Thanks in (Regret,regret,regret ...Damn..!!)
     
    JoeStrout likes this.
  13. Ghopper21

    Ghopper21

    Joined:
    Aug 24, 2012
    Posts:
    170
    Great question @timsk -- any chance you got around to doing those benchmarks? Would be in your debt if you did and could share your results!
     
  14. Ghopper21

    Ghopper21

    Joined:
    Aug 24, 2012
    Posts:
    170
    Never mind about @timsk about the benchmarks -- here are some that someone posted recently on Reddit. Good discussion there.
     
  15. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Comparing UnityEvent and regular C# delegates/events is comparing apples and oranges.

    I don't even have to look at the link to know UnityEvent will be slower. But it also does things that events don't do.

    I would love to benchmark it against my event system I wrote some time back.
    trigger_inspector_2.png

    I just made it free in my open version of my framework:
    https://github.com/lordofduct/spacepuppy-unity-framework/tree/master/SpacepuppyBase/Scenario

    editor parts:
    https://github.com/lordofduct/spacepuppy-unity-framework/tree/master/SpacepuppyBaseEditor/Scenario
     
    Last edited: May 23, 2015
  16. Ghopper21

    Ghopper21

    Joined:
    Aug 24, 2012
    Posts:
    170
    Care to explain? I don't see why UnityEvents have to be nearly 40x slower (not that it would matter in many cases). Why wouldn't they just be wrappers for C# events?
     
  17. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    Because UnityEvent works in the opposite direction of events.

    C# events are just wrappers around delegates. Which is just really an array of pointers to functions on objects. The function has a specific shape that it must conform to defined by the delegate type of the event.

    UnityEvent can't reference those functions as it's not exactly serializable. Also it has to connect everything up in reverse order. So instead you put in a list of what GameObject, the component on that GameObject, and the function of that Component that will get called, as well as any parameters that will be passed into the function as the function can take whatever shape it wants (within some boundaries/limitations that unity set up so that UnityEvent didn't get horribly complicated and can still work with serialization).

    To get this functionality, it has to use reflection to access the method to call, and then to invoke the method. This takes a lot more overhead than just calling an array of functions.
     
    Ryiah and Ghopper21 like this.
  18. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    So, because I have the images sitting here on my hdd, and angryant asked why i prefer maintaining mine as to using unity's.

    So in the image above you'll notice that you can select 4 different ways of the trigger (I call them triggers instead of events) call the triggerable objects:
    1) Call Method On Selected Target - this works just like UnityEvent
    2) SendMessage - does exactly that, working like classic unity messaging
    3 & 4) Trigger Selected Target / Trigger All On Target - this calls a specially shaped function on all components that implement an 'ITriggerableMechanism' interface that are on the target GameObject.

    We call this our "T & I system", where T's are components that trigger, and I's are components that receive messages.

    T_OnWeaponStruck
    I_PlayAnimation

    Now the thing is in UnityEvent I not only have to define the target GameOBject, but also what component and function needs to be called. What if I have MULTIPLE that need to be called... gotta set up every single one.

    Well here I just need to know the target, set to 'Trigger All On Target' (which is our default option, by the way), and it just triggers all of them. If down the line I decide I need to add some extra things to the target, I don't have to go and set up which get fired and don't. And I get to sort the order and delay of them as well.

    trigger_inspector_4.png

    This becomes so powerful that when designing levels, just using this and chains of GameObjects we can build entire cutscenes and scenarios out of this, without having to write a lick of code (which is great for my artist who can't program worth a bullhonky).

    We actually made this entire game "How Now, Sea Cow" in a week using it:
    http://triatami.itch.io/how-now-sea-cow
    http://jupiterlighthousestudio.com/island-mini-game-how-now-sea-cow/

    Note, I'm not saying this is unique to mine either. UnityEvent is this powerful as well.

    There's just parts of mine I like a little more. ITriggerableMechanism, and TriggerableTargetObject being the primary things.

    What TriggerableTargetObject is that these I's can be on really any GameObject. But may need to do something to a different GameObject. I_PlaySPAnimation may need to play an animation on a different GameObject in the hierarchy of this directly configured... OR, because the T includes the target that caused the event as an argument to the ITriggerableMechanism, you can actually target that thing.

    So say you have a T_OnEntityEnter that masks out for a tag that is 'Enemy'. It triggers a GameObject with 'I_PlaySPAnimation' on it, and includes the enemy as the argument. I_PlaySPAnimation just plays some animation of some name on the Animation component in that entity that is passed to it. Lets say that animation is named "Knockback". No matter what enemy enters this T_OnEntityEnter, may it be a croc, or a cultist, or a robot... that individual enemy will have the animation 'knockback' played on it, as long as it is defined for it (which means it can have a custom anim for each).

    This can even be daisy chained.

    So I have a simple I called 'I_Enable' that can enable or disable gameobjects or components. My designer has used these to create toggle switches.

    So he has a T_OnEntityEnter that masks for the Player only. It targets 2 GameObjects, thing is one of those GameObjects is set to inactive. So really only one of them will receive the message. But when it receives the message, and it plays this animation, spawns this particle effect, and plays some sound effects or other stuff... it ALSO has 2 i_Enables on it that disable itself, and enables the other gameobject target. This way the NEXT time that player enters the T_OnEntityEnter it does the other action. And this then can toggle back, or on to another 3rd GameObject for the 3rd, 4th,... etc.

    Another thing is I have an IObservableTrigger:
    https://github.com/lordofduct/space...SpacepuppyBase/Scenario/IObservableTrigger.cs

    All T's should implement this. It allows me in code to determine what events exist on the T, if there are 1 or many, and what the names of those events are.

    Then I have a 'T_AllTriggered':
    https://github.com/lordofduct/space...ter/SpacepuppyBase/Scenario/t_AllTriggered.cs

    This will observe anything that is IObserverableTarget for when its triggers/events get activated. This way we can delay an action until multiple things have happened.

    So say there are 3 tigger points in a room that open the door when all 3 have something standing on them. Each have T_OnEntityEnter components so that we know when someone has entered/left the trigger. When all 3 have triggered, that's when T_AllTriggered sends it message out, which opens the door.


    NOTE - not all T's and I's I described are in the open version of my framework, and are instead part of the other half of the system that is closed source for our games.
     
    Last edited: May 23, 2015
  19. shadowninjapie

    shadowninjapie

    Joined:
    May 22, 2015
    Posts:
    9


    wow thats cool. how did u make the message args thingie where u can select float or vector?
     
  20. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    That would be VariantReference
    https://github.com/lordofduct/space...lob/master/SpacepuppyBase/VariantReference.cs

    property drawer for it:
    https://github.com/lordofduct/space.../Inspectors/VariantReferencePropertyDrawer.cs

    This was made independent of the Scenario system, but was used by it. I use it a lot of places.

    It's just a class that allows me to store a inspector configurable value of any easily serialized type.

    Another similar class I use a lot is TypeReference:
    https://github.com/lordofduct/spacepuppy-unity-framework/blob/master/SpacepuppyBase/TypeReference.cs

    and it's property drawer:
    https://github.com/lordofduct/space...ase/Inspectors/TypeReferencePropertyDrawer.cs

    My whole framework is full of weird little things like this that just make my job easier. Been building it up for a while.
     
    Last edited: May 23, 2015
  21. shadowninjapie

    shadowninjapie

    Joined:
    May 22, 2015
    Posts:
    9
    ooh i see. so its basically just a class with a bunch of potential values then when you want to get the value u have to call ".StringValue" or w/e and ."Value" will return it as an object. then its just displayed a custom way with the property drawers. i thought it was like a generic thing or something where u have a generic message args and then through the inspector u selected the T of the generic and its value
     
  22. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,531
    I wish I could do that, but generics aren't serializable. This was designed to get similar functionality.
     
  23. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Sorry for kicking open this now-someone-stale thread, but I'm actually working on a remake of this tutorial as I threatened to do a few weeks ago. But this time, showing how UnityEvents can be employed to accomplish the same tasks with way less code.

    However, the tutorial page includes downloads for only the audio files. The minion is just a capsule and cube, I can handle that. But the explosion particle effect... it's a great little "pop" firework-like effect. Does anybody know where he got this? Or, can you point me to something similar?

    There are a ton of explosion effects on the asset store, but I haven't found anything that makes a cute little pop like this.

    Once I have that, I'll wrap this tutorial up and get it posted in the next day or two.

    Thanks,
    - Joe
     
    hopeful likes this.
  24. RockoDyne

    RockoDyne

    Joined:
    Apr 10, 2014
    Posts:
    2,234
    If memory serves, I think he mentions it's from the survival shooter project. Possibly/probably wrong though.
     
  25. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    OK, I couldn't find it there, but I found something similar in the KTK Effect Sample Set in the asset store.

    So! With no further ado, here's what I spent my morning on:

    The Real Power of UnityEvent

    This blog post introduces the topic, and then links to the video. Since the topic is pretty well introduced in this thread already, I guess I'll just embed the video directly:



    I welcome any comments, criticisms, or pizza donations.
     
    Ryiah, IgorDemchuk, ashley and 5 others like this.
  26. Deleted User

    Deleted User

    Guest

    Cliffs?
     
  27. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    I had forgotten about UnityEvent and haven't even tried it yet. I may still go back and rewrite my own event system though which includes components to register events. I'm curious, does UnityEvent support passing arguments? Also, does it work like a WeakDelegate where a destroyed GO causes the events to automatically unregister or do you have to handle that yourself?
     
  28. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Yes, it supports passing arguments; these can either be provided by the invoker of the invent, or provided where you hook them up in the UI. It's neat stuff, which you can see where I invoke the Logger component in the video.

    As for your second question, it depends on how the event is hooked up. If it's hooked up via the Unity editor, then that is called a "persistent listener," and it's a weak reference that automatically goes away when the target object is destroyed. But if it's hooked up in code via AddListener, then this is a strong reference, and you have to call RemoveListener when the object is destroyed to avoid getting an error the next time the event is invoked. This is demonstrated in the video.
     
    Dustin-Horne likes this.
  29. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    As in, summary for those too busy to watch the video? Sure thing:
    1. Create an EventTriggerTest script, with public UnityEvent properties (like "public UnityEvent spawnMinions"), that it invokes in response to a keypress (e.g. via "spawnMinions.Invoke()").
    2. Attach that to something global, like the main camera.
    3. Attach a Logger script (which has public methods to log various strings) to something global (I made a new object called MinionManager).
    4. Use the Unity editor to invoke Logger when on those EventTriggerTest events. (Look ma, no code for this step! And no magic strings either.)
    5. Add the Spawner script (taken from Adam's original demo, minus all the notification-system silliness) to MinionManager, and hook its public Spawn method up to the EventTriggerTest. Run, press a key, and observe minions spawning.
    6. For destruction, we need two things: (A) a static UnityEvent that lives in just one place (SelfDestruct.destroyEvent), and (B) the SelfDestruct component to add/remove itself to this static event at runtime.
    7. We also need some way to trigger that static UnityEvent. Since static properties don't appear in the inspector, I made a simple wrapper class: a MonoBehavior with a public method that simply calls SelfDestruct.destroyEvent.Invoke(). Throw this onto MinionManager, and hook it up to the appropriate event in EventTriggerTest.
    That's it... there's no step 8! But all this is way less code than the original demo, and safer code too (no magic strings, almost no possibility of dangling references, etc.) And I think it demonstrates good factoring of the design into simple, one-trick scripts that either invoke UnityEvents when something interesting happens, or have public methods that can be invoked in response to UnityEvents. All the classes are neatly self-contained and encapsulated, and nobody has to delve into anybody else's business.
     
    Deleted User likes this.
  30. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Oh yeah, I meant to say: I had a system like that too. I think a lot of us did! But I'm ditching mine in favor of UnityEvent, mainly for the really nifty editor support. If it were runtime-only, UnityEvent wouldn't have any great advantages I can see over other delegation/notification systems... but hooking these things up in the scene is awesome. In my opinion it is the major piece that has been missing from Unity's component architecture from the very beginning.
     
    dterbeest likes this.
  31. hopeful

    hopeful

    Joined:
    Nov 20, 2013
    Posts:
    5,684
    Probably best to post the scripts here? Or is this going to some other official space?

    EDIT: Ah ... I had overlooked or forgotten about the link to the blog that's in the title of the video.
     
    Last edited: Jun 4, 2015
  32. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    hopeful likes this.
  33. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Very cool! I couldn't watch the video here in my office but I'll check it out tonight.
     
  34. Cromfeli

    Cromfeli

    Joined:
    Oct 30, 2014
    Posts:
    202
    *Offers pizza*

    That is absolutely great tutorial! Love it, thank you so much for taking the effort o_O
     
    JoeStrout likes this.
  35. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    Have you found any good way to hook up several arguments in the editor? As in a way to have the editor draw something like a UnityEvent<string, int>?

    If you set up something like this:

    Code (csharp):
    1. [Serializable]
    2. public class UnityEventStringInt : UnityEvent<string, int> { }
    It'll draw just like a normal UnityEvent; you can select methods with zero or one arguments. Which is useless.

    I've got a setup with a trigger box that's supposed to have a nearby NPC say something. This means showing a text box, and then removing it again after a set time. The method I want to invoke is this one:

    Code (csharp):
    1. public void ShoutOut(string text, float timeout) {
    It would be very convenient to hook it up to this:

    Code (csharp):
    1. public class UnityEventStringIntWrapper : MonoBehaviour {
    2.  
    3.     public UnityEventStringInt myEvent;
    4.  
    5.     void OnTriggerEnter(Collider other) {
    6.         if( //other is player character)
    7.             myEvent.Invoke();
    8.     }
    9. }
    but, alass, that's impossible. Looking through the UnityEventDrawer class, the method that finds the type parameters can take several arguments, but it's only invoked looking for a single one. I'm assuming that the engineers never got around to adding support for methods with several arguments. For now, it seems like the only way to use several-argument UnityEvents is to write custom wrapper classes for every combination of argument types, have fields for the arguments, and then invoke those.
     
    lermy3d likes this.
  36. squared55

    squared55

    Joined:
    Aug 28, 2012
    Posts:
    1,818
    Forgive my ignorance, but what does this do? Does it mean you can call a method on every script at once?
     
  37. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    Are you asking about UnityEvents, or are you referencing my post?
     
  38. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I haven't tried it, but I would think you could make a small serializable class that wraps up the two arguments. Something like this (if you forgive the horribly generic naming):

    Code (Csharp):
    1. [System.Serializable]
    2. public class StringInt {
    3.     public string stringValue;
    4.     public int intValue;
    5. }
    6. [Serializable]
    7. public class UnityEventStringInt : UnityEvent<StringInt> { }
    8.  
    Now this event type takes only one parameter... but it's a parameter that has both pieces of data you care about. With a bit of luck (and good generic coding on the part of the Unity engineers), this ought to appear with a disclosure triangle you can open up to specify both arguments.

    If you try it, please report back and let us know what you find!
     
  39. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    What about writing one generic one... so if you need two arguments:

    Code (csharp):
    1.  
    2. public class EventArgument<T, U>
    3. {
    4.    public T Value1 {get; set;}
    5.    public U Value2 {get; set;}
    6. }
    7.  
    Then you'd create it as say:
    Code (csharp):
    1.  
    2. var args = new EventArgument<string, float>();
    3. args.Value1 = "Test to say";
    4. args.Value2 = 25.17f;
    5.  
     
  40. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    No. UnityEvents are a way of calling a method on specific "listeners" that have been hooked up to the event. You can do this hooking up either in the Unity editor, or at runtime. If you watch the video, you'll see both methods used.

    The point is to decouple your classes. Suppose you have class A (e.g. something that processes input), and class B (which does something, like spawning a bunch of minions). The old/bad/obvious way of connecting these is for class A to know about class B and directly call the class B method. But now the classes are coupled together; you can't give me just your class A, because it won't compile without class B. You can't change class B's interface without class A breaking. You can't easily decide that, in addition to invoking class B, you want class A to also call class C and do some debug logging (well, you can, but you have to modify the code of class A).

    With UnityEvent, all these problems go away. Class A declares a UnityEvent for when the key is pressed, and that's it; it does nothing else except invoke that event. Class B declares a public method to spawn those minions. And then, in the scene editor, you can connect these together, as well as connect that event to other things as you wish. No class knows or cares anything about the others. You can reuse class A or class B in a completely different context, and everything is hunky-dory.
     
    squared55 likes this.
  41. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    That's a great idea! Sadly, the UnityEvent drawer that's used in the UnityEvent inspector gui only accepts methods declared with either 0 arguments, or one argument with one of the types:

    - float
    - int
    - string
    - bool
    - UnityEngine.Object

    Which means it won't work :(

    It'd be really great if the inspector grabbed the default drawer for whatever argument the method accepted, and painted that, but that's not the case.
     
    lermy3d likes this.
  42. Dustin-Horne

    Dustin-Horne

    Joined:
    Apr 4, 2013
    Posts:
    4,568
    Oh yeah, that wouldn't fix the property drawer issue sadly. You'd have to do something really hacking like storing a Dictionary<string, EventArguments> in a manager class... then use the key as your event argument and look up the proper EventArguments from the manager dictionary when the event is fired.
     
  43. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Doh. That's a shame. Well, if you file a feature request, please post the link here, and I'll certainly sign on. UnityEvents are still pretty new; I think we can hope for enhancements in future versions of Unity!
     
  44. sluice

    sluice

    Joined:
    Jan 31, 2014
    Posts:
    416
    Nice video @JoeStrout !
    Clear and easy to follow. :)
     
    Cromfeli and hopeful like this.
  45. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,334
    Second that, by the way, great video.
     
    hopeful likes this.
  46. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Thanks guys! It's good to know some people found it helpful.
     
  47. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080

    I really enjoyed the video but I have one question. How would you use the event system to cause just one minion (out of a bunch on screen at the same time) to explode? Preferably one that was either clicked on or tapped on?
     
  48. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Interesting question. If this is something a component on the minion itself can detect, then you could just have that detector script invoke an event, and hook that up to whatever effects you want (such as exploding) in the prefab. When that prefab gets instantiated, any event handlers within it get properly hooked up in the new instance.

    However, for handling a click/tap, having each minion hit-test that itself isn't a very efficient way to go. It's generally much better to have one global object that detects the mouse-down, does a single ray-cast to see what it hits, and then notifies that object. UnityEvent isn't a good fit in this case; instead, you might use something like Unity's messaging system to invoke a method on any component of that object that implements an appropriate interface.
     
  49. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    Wow! That was a fast response. Thanks. I'll look into Unity's Messaging System. But looking at the UnityEvent docs I see these: IsPointerOverGameObject, SetSelectedGameObject, currentSelectedGameObject. They may be able to be used for what I want to do. Thing is, they sure are not explained very well (actually, not explained at all). I'm going to do some searching here and in Unity Answers for more info on those.
     
  50. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    ExecuteEvents.

    It if it's always in response to input, use a physics raycaster and an event system.