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.1%
  2. No, but I still don't see what's the big deal.

    5.2%
  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.3%
  5. Yes, and I use them all the time. Where have you been?!?

    22.4%
  1. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    BoredMoron, I know I should use an EventSystem. My question is how to use the EventSystem.
     
  2. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Why do you "know" that you "should" use an event system for this specific case?
     
  3. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    Lol, he called you BoredMoron.

    @TokyoDan - it might be easier to just have a simple script that listens for the OnMouseDown message and attached to the GameObject with the collider on it that represents the clickable region.

    Just explode it in there.
     
    Deleted User likes this.
  4. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    @angrypenguin, It's not so much that I 'know" as much as it is that I wonder if there is a way to do what I want by using an Event System. For example even though all the minions are listening for a specific event, but for a special case I want only one specific minion to act on that event.

    @lordofduct, Yes, that is what I'm starting to think. Thanks.
     
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Listening for an event doesn't mean it has to be acted upon. I often raise events and then have listeners make some kind of internal decision about whether to or how to react to it.

    In this case I wouldn't use that approach, though, because it seems to me that the calling code probably already needs to know which specific minion it's trying to do a specific thing with. Eg: you did a raycast and got a reference to it or it's already had an internal callback called or something like that.
     
  6. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    @angrypenguin. Yeah. I was thinking of using flags in the minions. e.g. If (IsSelected) then act on event. But you are right. This approach is not really good for what I want to do. Thanks.
     
  7. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Why does the system does not accept to use several parameters so it can be re used to launch pretty much any function, like NGUI EventDelegate, this was quite a disappointment to me... keep trying Unity, you will get it well by the next iteration.
     
  8. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    What do you mean? It can work with up to 4 parameters. If you need to pass more than 4 bits of data then you can wrap some of them in a class or struct (just like standard .NET events).
     
  9. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I imagine he's talking about the Unity editor support. That only supports a single parameter, and has some annoying limitations — to me, the worst one is that it doesn't support enum types. You should be able to invoke the event and simply the enum value you want to pass in from a pop-up (just like you do when setting public enum properties).

    So, yeah, there's room for improvement, but it's still pretty full of awesome.
     
    angrypenguin and lermy3d like this.
  10. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    Lately if I need to pass more than one parameter to something that can handle only one, I just pack everything into one integer and then in the function/event handler I use bitwise operators to extract the information.
     
    lermy3d likes this.
  11. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Thank you JoeStrout, so yes I was referring to the Inspector, for one second I thought that the last version 5.2.0f2 had already fixed that, I cannot test where I am right now.

    I think UnityEvents are on the right path but it is currently very primitive inspector wise regarding all this current limitations, for me is a big thing because I already could enjoy that with NGUI EventDelegate which did made a great job with reflection.

    That could make our lives very easy and would remove us from supporting a communication byte like TokyoDan suggested, which in the long run could be prone to errors, because if any of the functions change his parameters or if you forget to update your 'translator' method it could lead to an unwanted behavior easily. So the maintenance cost is higher and very risky.

    Hope all of this could be a real feature we all can enjoy in a not distant future!
    Have a nice one.
    Lermy
     
    Last edited: Aug 30, 2015
    Deleted User likes this.
  12. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Oh, I see. I can hook up a dynamic call with multiple parameters, but not a static. Is that what you meant? Fingers crossed that gets addressed in the not-too-distant future.
     
    JoeStrout and lermy3d like this.
  13. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Them fighting words right there. Prepare to be sent to the learn section! ;) ;)

    To use the EventSystem for input detection you do the following
    1. Create an EventSystem GameObject in your scene. There will already be one if you are using the UI system.
    2. Add a PhysicsRaycaster or Physics2DRaycaster to your main camera.
    3. Add an appropriate collider to you scene objects.
    4. Add a component to you scene objects that implements any of the EventSystem interfaces. An EventTrigger is a good place to start.
    This video sort of explains it obliquely

     
    hopeful and lermy3d like this.
  14. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    Yup. Runtime listeners can be added with pretty much any parameters. Persistent listeners are limited to a single parameter of a limited set of types.

    You can work around this by wrapping a set of parameters up in a UnityEngine.Object
     
  15. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Exactly BoredMormon, and the question still remains, why they restricted the amount of parameters!? aesthetics? hahaha! is just ridiculous!

    Thank you for the very instructive tutorial by the way!
     
  16. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    It's mainly simplicity rather then aesthetics. An is pectin that tries to do everything ends up very messy to code and use. I've tried it.

    Glad you liked the video. There are more like it on my channel.
     
  17. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Totally true, is Too simple! If you have a complex function you have to split it in the inspector in as many functions as the original parameters you actually needed, and then this simplicity overloads your visual events maintainability. It is like they are building tools for babies instead of for developers. :(
     
  18. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    BoredMormon OMG. I'm sorry I didn't mean to call you 'BoredMoron". I was not taking my time and properly reading people's handles.
     
    lermy3d and hopeful like this.
  19. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    Saying its "restricted" implies that its willful and deliberate. Its more likely that that's just where they were up to at release time.

    If they always held off until they were100% happy before releasing something they'd never release anything. ;)
     
    lermy3d, hopeful and Kiwasi like this.
  20. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    I am glad you think that way! I truly hope your assumption is the correct one, for real.

    Now that we are going deeper in how we would love to improve UnityEvents, there is also one missing thing that haven't been mentioned in this list and it is the support for functions with default parameters.

    I cannot remember if in NGUI events delegates we could use a function that received default parameters or if the EventDelegate class was always letting you override the value (I'll check tomorrow and post you back) but the thing is that a really cool way of managing this would be if the system could detect by reflection if the function has default parameters and allows you to use that value or to use a custom.

    Right now this kind of functions are not allowed to execute, so a little bit of love from Unity to support them would be really nice!
     
    Last edited: Sep 1, 2015
  21. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    I came across the need of setting a new parent for a GameObject and therefore passing the the GameObject and the Parent Transform to the general function using UI events. Does anybody knows a workaround for multiple parameters?
     
    Last edited: Sep 2, 2015
  22. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Also, have you noticed that there is no easy way to reorder the events!?? Like a drag and drop kind style! that is also cumbersome sometimes o_O:(
     
    Deleted User likes this.
  23. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    @lermy3d pack everything you need in a single integer then use bitwise operators to extract it.
     
  24. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Thanks TokyoDan, but in this case a need a reference to a Transform on the scene hierarchy, I cannot pack that into an integer, have you achieved this with that method?
     
  25. Deleted User

    Deleted User

    Guest

    It shouldn't be too hard to create a custom inspector for UnityEvents with more than 1 parameter, maybe just time consuming. Maybe I'll start working on it. Anyone want to help?
     
    lermy3d likes this.
  26. Deleted User

    Deleted User

    Guest

    I think UnityEvents support any type that derive from Unity.Object. I haven't tested it yet, but would it not be possible to have a container class that inherits from Unity.Object and use it as a parameter?
     
  27. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    That's deliberate. You aren't supposed to rely in events being called in order, and there is no guarantee that future implementations will honour inspector order.

    Tread lightly.
     
  28. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Okey, thanks, although right now they are respecting that pretty much well, it seems they are executing events in the same order they appear on the list. I just had to rearrange some of the events because I was destroying the current GameObject from wich they were executed before getting to the final event, setting the destroying event to be the last one worked great for me. :)
     
  29. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    I would gladly give a hand with this, I am going to check if there is some drawer for the UnityEvents and what they are doing there. I already helped fixing the EventDelegateDrawer from NGUI once so we can use that as base code for this even when they are not the same, it is a head start at least. I will dig into my files and share this custom drawer with you.
     
    Deleted User likes this.
  30. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    @lermy3d why would you want it to care about the order things are done with. Having code where the order the events get fired matters, kinda breaks the point of using events in the first place.
     
  31. Deleted User

    Deleted User

    Guest

    Depends on the scenario. If you have a scenario where you want a GameObject to execute some functions then be destroyed, then yes order matters.
     
    lermy3d likes this.
  32. passerbycmc

    passerbycmc

    Joined:
    Feb 12, 2015
    Posts:
    1,741
    if you wanted a gameObject to execute some methods than be destroyed. It should do that its self using its own method that is invoked by the event system.

    Or you use multiple events that are invoked 1 after a other.
     
  33. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I've had situations where the order matters. It's easy to say "don't do that" in the abstract, but in real life, it occasionally comes up. Having to use some other mechanism to chain your events and enforce a certain order adds unnecessary pain.

    So, I'm with @lermy3d on this one — Unity should commit to respecting the order (if indeed they haven't), and there should be an easier way to reorder them.
     
    lermy3d likes this.
  34. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    Yeah, my designer needed to ensure order with our event system.

    So I make sure the that our 'triggers' process the registered events in the order they appear in the list. And the inspector uses ReorderableList to allow easy moving them about.

    And the receivers (which can have multiple receivers on them as we rely on gameobject rather than components) have an 'order' variable on them that ensures the order regardless of the component position on the gameobject.

    I tried making the argument of doing this or that, and he was just like "dude... so I have to do extra work to ensure order. Why not just give me a property?", I was like "good argument."
     
    Last edited: Sep 3, 2015
    lermy3d likes this.
  35. TokyoDan

    TokyoDan

    Joined:
    Jun 16, 2012
    Posts:
    1,080
    Nope, Sorry. That is a horse of another color.
     
    lermy3d likes this.
  36. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Hello guys, I couldn't find anything at all regarding UnityEvents namespace, so no luck on that, but I found my old scripts for events. I recently updated them this morning since I needed those extra parameters and right now we have UI events using multiple parameters, we can name each event and we can fold them as well.

    Here is my to do list:
    -Add parameter types and names before showing method list.
    -Replace 'Arg' with the actual name of the parameter if possible by reflection.
    -Use a specific field instead of the fixed reference 'ObjectField' for primitives types like: string (TextField), int (IntField), float (FloatField), double (DoubleField) and bool (Toggle).

    Here is how it looks like:

    custom Events.jpg

    I hope this serves a base code for improving UnityEvents which is the actual goal.
    Let us know if anyone upgrade the code!
    Have a nice one!
    Lermy
     

    Attached Files:

    Last edited: Sep 4, 2015
    Deleted User likes this.
  37. Meltdown

    Meltdown

    Joined:
    Oct 13, 2010
    Posts:
    5,822
    lermy3d likes this.
  38. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Thank you Meltdown! Does this system allows you to link events using the inspector so you can create prefabs with the logic arranged there?
     
    Last edited: Sep 4, 2015
  39. Deleted User

    Deleted User

    Guest

    AdvancedCSharpMessenger fits a different niche than UnityEvents I would say. I use a slightly modified version of AdvancedCSharpMessenger too.
     
  40. Meltdown

    Meltdown

    Joined:
    Oct 13, 2010
    Posts:
    5,822
    You could do this, just create a script that allows you to drop in prefabs, then do what you want with those prefabs when the event is fired.
     
    lermy3d likes this.
  41. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Hello guys! I have good news for you! The custom EventDelegate implementation is now completed. We are now showing parameter type and name and we can now enter parameter values directly, for this, only the use of PropertyFields was needed for the primitive fields.

    As you all now features method invocation using multiple parameters is indeed supported.

    Here are some screen shots and a snippet on how to use:

    Code (CSharp):
    1. public List<EventDelegate> OnEnableEvents;
    2.  
    3. void OnEnable()
    4. {
    5.     if(OnEnableEvents.Count > 0)
    6.         EventDelegate.Execute(OnEnableEvents);
    7. }
    Method menu selection:

    method selection menu.jpg

    Events display:

    custom Events 2.jpg

    Enjoy! Any suggestions please share!
    Lermy
     

    Attached Files:

    rakkarage and Deleted User like this.
  42. Deleted User

    Deleted User

    Guest

    Just tried it but it's very buggy. Most of the time I select a method I get the error "Could not find method x" even if it's just a normal method.
     
  43. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Thank you @supremegrandruler, I didn't had any errors when using it, let me try an empty project, or if you are using a test project for that and you are having the error there could you please attach it, if otherwise could you please copy/paste the message log so is easier to detect the bug, thanks a lot for the feedback!
     
  44. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Hello @supremegrandruler, I found two bugs for the way I was displaying the methods, they are now fixed and I also made a code clean up. Just remove the EventDelegate folder before importing this new version.

    Also worth pointing out that overloaded methods are not currently supported yet, only non overloaded methods for now until I figure out a simple way of doing this. Overloaded methods are now automatically filtered. (sorry the delay I had some trouble getting this right)

    Let me know how it goes!

    Best regards,
    Lermy
     

    Attached Files:

    Deleted User likes this.
  45. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    There is huge delay with the List.Sort function, if you start typing you will get to notice it. I will probably have to save the method list for an unchanged component.

    Otherwise I will have to comment line 551 in EventDelegateDrawer.cs but we will get no method sorting though, :(.
     
    Last edited: Sep 7, 2015
  46. ashley

    ashley

    Joined:
    Nov 5, 2011
    Posts:
    84
    Thank you so much for this! Was really helpful to watch this after having recently watched the original and you explained it in a very clear way. Appreciate the project being included on your blog too.

    Will send pizza.
     
    JoeStrout and lermy3d like this.
  47. Deleted User

    Deleted User

    Guest

    Thanks I'll try it again. :)
     
  48. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    @supremegrandruler, may I suggest you start a separate thread for your own event system, and keep this one (now "mostly") about UnityEvent and the built-in functionality that goes with it, just to avoid confusion?
     
    lermy3d likes this.
  49. Deleted User

    Deleted User

    Guest

    Not sure what you're talking about because I never discussed my own "event system".
     
    lermy3d likes this.
  50. lermy3d

    lermy3d

    Joined:
    Mar 16, 2014
    Posts:
    101
    Is my fault guys, Sorry for making the thread subject to go astray! I will create a new thread to avoid people getting confused between UnityEvents and the EventDelegate system.
     
    Last edited: Sep 8, 2015
    JoeStrout likes this.