Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Ability to add enum argument to button functions

Discussion in 'UGUI & TextMesh Pro' started by Slev, Sep 26, 2014.

  1. Slev

    Slev

    Joined:
    Sep 8, 2012
    Posts:
    148
    A feature I would love to see is for buttons to be able to call functions with an enum type argument for instance...

    Code (csharp):
    1.  
    2. public enum type {
    3.   fire, water
    4. }
    5.  
    6. public void SetType(type t) {
    7.   //content
    8. }
    9.  
    Currently buttons don't acknowledge these functions as being available. It would be incredibly nice if we could not only see these functions, but assign an enum value to pass in.
     
    awsapps, normus28, useralpha and 8 others like this.
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    It would be nice. Until then, having a string or int version of the function that then calls the enum version of it would be a usable workaround.
     
  3. Capn_Andy

    Capn_Andy

    Joined:
    Nov 20, 2013
    Posts:
    80
    Also requesting this! It would be very handy to have "safe" inputs on our buttons.
     
    awsapps and rakkarage like this.
  4. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,773
    Hmm... Something like this, are you thinking?
    Code (csharp):
    1.  
    2. [RangeParameter(0f, 100f)]
    3. public void SetSomeFloat(float param) {
    4.  
    And then the UI displays it as a slider?
     
  5. Tim-C

    Tim-C

    Unity Technologies

    Joined:
    Feb 6, 2010
    Posts:
    2,221
    Hi, we'll take this as a feature request. It won't make it in for v1.
     
    AlonMixed, DonPuno, awsapps and 8 others like this.
  6. Slev

    Slev

    Joined:
    Sep 8, 2012
    Posts:
    148
    Any time is better than never. Thanks Tim!
     
    AlonMixed likes this.
  7. deadfish90

    deadfish90

    Joined:
    Oct 20, 2012
    Posts:
    3
    Any update on this feature implementation yet?
     
    AlonMixed likes this.
  8. massey_digital

    massey_digital

    Joined:
    Apr 28, 2013
    Posts:
    94
    I was just hoping to use this feature myself for level control :]
     
    AlonMixed likes this.
  9. Immanuel-Scholz

    Immanuel-Scholz

    Joined:
    Jun 8, 2013
    Posts:
    221
    This would be awesome (if it works for custom defined PropertyDrawer and DecoratorDrawer), although if ever multiple parameters are going to be supported, then its probably necessary to put the attribute on the parameter:

    Code (csharp):
    1.  
    2. public void SetSomeFloat([RangeParameter(0f, 100f)]float param) {
    3.  
    However, I am not sure how the current interface of the PropertyDrawer could fit in here (as the drawer usually gets a whole line to play with and should print out the property label as well - which can even be potentially larger.

    Still... IMHO, an robust UI for an event system is a big big plus for Unity. (You also should put someone to look into displaying dynamically registered events in the UI during playmode. Its not impossible. Just hard. And you are about solving hard problems, right? :p )
     
  10. quizcanners

    quizcanners

    Joined:
    Feb 6, 2015
    Posts:
    109
    +1, was looking for this feature.
     
  11. MikeCoderMore

    MikeCoderMore

    Joined:
    Sep 22, 2013
    Posts:
    61
    I also need this
     
  12. rbisso

    rbisso

    Joined:
    Jul 13, 2011
    Posts:
    29
    Would be great to have, thank you!
     
  13. Green-Sauce-Games

    Green-Sauce-Games

    Joined:
    Mar 27, 2014
    Posts:
    71
    Any news on this?
     
    adrianjmejias likes this.
  14. MapuHoB

    MapuHoB

    Joined:
    Aug 17, 2014
    Posts:
    50
    Same here.. would like to have this feature as well!
     
    AlonMixed and adrianjmejias like this.
  15. tanoshimi

    tanoshimi

    Joined:
    May 21, 2013
    Posts:
    297
    Given the existence of System.Enum.Parse, isn't it pretty straightforward to create an overload of your event method that accepts a string parameter?
     
  16. jpthek9

    jpthek9

    Joined:
    Nov 28, 2013
    Posts:
    944
    Yes, it's straightforward but the results are less satisfactory. With a string, you're not restricted to inputting only valid names. With an enum, you can't make a typo.

    It's been a year already. Enum parameters isn't a fancy or complicated feature, but it needs to happen.
     
  17. MapuHoB

    MapuHoB

    Joined:
    Aug 17, 2014
    Posts:
    50
    Agree!
     
    jpthek9 likes this.
  18. RakshithAnand

    RakshithAnand

    Joined:
    Jun 30, 2013
    Posts:
    56
    Ah waiting for this. It would be useful :)
     
  19. M0rph3v5

    M0rph3v5

    Joined:
    Aug 15, 2012
    Posts:
    24
    Would like this as well, my work around at the moment is to pass a script and have that script have the type.
     
  20. Marble

    Marble

    Joined:
    Aug 29, 2005
    Posts:
    1,268
    Another drop in the bucket.
     
    Yiming075 likes this.
  21. DenizCetinalp

    DenizCetinalp

    Joined:
    Feb 8, 2014
    Posts:
    16
    Add me to the list of people requesting this feature.
     
  22. cadpeople

    cadpeople

    Joined:
    Nov 6, 2014
    Posts:
    21
    This would be a very valuable feature.
     
  23. phil-Unity

    phil-Unity

    Unity UI Lead Developer

    Joined:
    Nov 23, 2012
    Posts:
    1,226
    Its been added to our list of things to do. I know you say its not complicated but from the inspector interface the addition is not as simple as just saying "use a enum" so will take time.
     
    unnanego, AlonMixed, awsapps and 9 others like this.
  24. Harpoon

    Harpoon

    Joined:
    Aug 26, 2014
    Posts:
    20
    I too would like to see this implemented.
     
  25. TheNinjassin

    TheNinjassin

    Joined:
    Jun 16, 2014
    Posts:
    1
    I too am adding my general sentiments of concurrence to this post.
     
  26. number545266666

    number545266666

    Joined:
    Jan 22, 2016
    Posts:
    1
    This might have been mentioned already, but a quick work around is to have a script with a public enum variable for you to set in the inspector. Then have a a public method in your new script to call the original method. You can then get the button's OnClick to call the new method instead and pass your new script's enum value. A little extra work, but it works quite nicely.
     
    MGGDev, SergPutiak and eses like this.
  27. Totalschaden

    Totalschaden

    Joined:
    Dec 14, 2013
    Posts:
    44
    Would be nice to have.
     
  28. mustumasti

    mustumasti

    Joined:
    Mar 19, 2011
    Posts:
    14
    +1 to this. Love typesafe!
     
  29. Thelo

    Thelo

    Joined:
    Sep 13, 2009
    Posts:
    98
    I would also like to have the ability to pass enum values to my UI callbacks.
     
  30. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    433
    I'd like to have it. Though two years is definitely too long for a feature request.
    As said before, if you need a workaround, make a function take string as parameter, then convert it by this Parse().
    Code (CSharp):
    1. public void Parse(string myString)
    2.     {
    3.         try
    4.         {
    5.             MeEnum enumerable = (MeEnum)System.Enum.Parse(typeof(MeEnum), myString);
    6.             //Foo(enumerable); //Now you have your enum, do whatever you want.
    7.         }
    8.         catch (System.Exception)
    9.         {
    10.             Debug.LogErrorFormat("Parse: Can't convert {0} to enum, please check the spell.", myString);
    11.         }
    12.     }
     
    Last edited: Mar 11, 2016
  31. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    373
    uGUI is officially available at github, thus you can modify the source code to have enums available as well. Not sure if it`s worth the effort though.
     
  32. eses

    eses

    Joined:
    Feb 26, 2013
    Posts:
    2,637
    @zhuchun - Hi, just out of curiosity - did you try what @number545266666 mentioned?

    I've done some hacks like the one below, note that I'm just learning this stuff, it's not a solution to OP's question, but maybe it gives some ideas at least.
    Enum used is defined in this script, it can't just be any enum, but you can put any method to OnClick slot in inspector, that has this enum as parameter.

    Code (csharp):
    1.  
    2. [Serializable]public enum State{None,Off,On}
    3. [Serializable]public class CustomEvent : UnityEvent<State>{}
    4.  
    5. public class Test: Selectable, IPointerClickHandler
    6. {
    7. [Header("Set this State")]
    8. public State setState;
    9.  
    10. [Header("Fired When Clicked")]
    11. public CustomEvent OnClickCustom;
    12.  
    13. //This fires the OnClickCustomevent when button (this selectable class) is clicked
    14. public void On PointerClick(PointerEventData eventData)
    15. {
    16. OnClickCustom.Invoke(setState);
    17. }
    18.  
    19. //Addthis(or any method with similar paramaters) to your custom Event in inspector
    20. public void Enum Consumer Method(Statestate)
    21. {
    22. Debug.Log("State is:"+setState.ToString());
    23. }
    24. }
    25.  
     
  33. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    433
    That's cool, in my case I put that Parse() inside a static class so I can use it anywhere. I'm too lazy to implement interfaces for a click event :p
    So, @Wrymnn you're right, open source is good for everyone. But I don't really like to dig in a giant project to make a patch. Last time I did that was 2 years ago, fixed a crashed bug of WCF on mono and it's still "Confirmed" on their bugzilla now. Well, I don't judge, it's all about efficiency :]
     
  34. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Yes totally bump for this (OP). enums are faster and better to use then string with allocation..
     
  35. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    373
    @zhuchun you dont have to make request, just code it for yourself, just into your project.
     
  36. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    433
    lol calm down dude, I don't think feature request is for oneself, it's for people who stuck in afterwards. Just like you walk on a road and find there's a hole, so leave a tag there hoping someone can fix it someday.
     
    EliseRealcast likes this.
  37. Wrymnn

    Wrymnn

    Joined:
    Sep 24, 2014
    Posts:
    373
    You dont undetstand xD

    You can download source code, modify it and use it in your project. Thats one of reasons why it was published.

    You dont have to make request on github in order to use enums in events in your project when you code it yourself.
     
  38. Zaflis

    Zaflis

    Joined:
    May 26, 2014
    Posts:
    438
    Would you see about editing possible typos in the post, i guess it could be useful for some. I found it curious. Anyway i'm not completely following what it does, like here:
    Code (CSharp):
    1. public void Enum Consumer Method(Statestate)
    2. {
    3. Debug.Log("State is:"+setState.ToString());
    4. }
    It's Enum type but you don't return anything. Then the parameter is possibly mixing type and name, and not using it anywhere?
     
    Last edited: Jun 17, 2016
  39. zhuchun

    zhuchun

    Joined:
    Aug 11, 2012
    Posts:
    433
    Hi, FYI the key is to implement this interface http://docs.unity3d.com/ScriptReference/EventSystems.IPointerClickHandler.html
    That ConsumerMethod is just a foo(), take an Enum as its parameter and return void. Good luck :)
     
  40. KazYamof

    KazYamof

    Joined:
    Jun 26, 2015
    Posts:
    59
    Shame of Unity. 2 years and NOTHING????
    Giz... We can do almost nothing from the inspector!
     
  41. RotaryBlaze

    RotaryBlaze

    Joined:
    Dec 18, 2015
    Posts:
    7
    My fix was to get Unreal, lol. Unreal fixes a lot of Unity problems and headaches. Unfortunately I have to use Unity at work.
     
  42. Rogerio-Castro

    Rogerio-Castro

    Joined:
    Mar 18, 2014
    Posts:
    3
  43. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    597
    Nearing 3 years, any updates?
     
  44. sbtp

    sbtp

    Joined:
    Jul 26, 2013
    Posts:
    7
    +1 Will still bump for this after 10 years.
     
    Menion-Leah, tehusterr and kobyle like this.
  45. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Ok guys, so i have this enum solution i would like to share with the community.
    This is a script that is attached to a image under Canvas.

    Code (CSharp):
    1. public enum ButtonType
    2. {
    3.     JoyStick,
    4.     JumpPress,
    5.     Shoot1,
    6.     Shoot2
    7. }
    Code (CSharp):
    1. public ButtonType buttonType;
    2.  
    3. // Must implement this interface  IDragHandler,  IPointerDownHandler, IPointerUpHandler
    4.  
    5.     public virtual void OnPointerDown(PointerEventData data)
    6.     {
    7.         if (buttonType == ButtonType.JumpPress)
    8.         {
    9.             PlayerScript.GetComponent<Player>().JumpPlayer();
    10.         }
    11.  
    12.         if (buttonType == ButtonType.Shoot1)
    13.         {
    14.             PlayerScript.GetComponent<Player>().Skill1();
    15.         }
    16.  
    17.         OnDrag(data);
    18.     }
    19.  
    20. public virtual void OnDrag(PointerEventData data)
    21.    {
    22.      if (buttonType == ButtonType.JoyStick)
    23.      {
    24.            // Movement here
    25.      }
    26. }
    27.  
    28.     }
     
  46. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    You can also do this as statemachine, but the example is taken from one of my mobile games.
     
  47. llamagod

    llamagod

    Joined:
    Sep 27, 2015
    Posts:
    76
    The solutions given so far are either weird, vague, specific, requires you to redo a ton of stuff or obvious, but with obvious giant flaws as well. Unity has failed to do anything in the last 2 years. Because this has been up so long and so many people are interested I have made a solution. The reason for enums not being available is basically lack of polymorphism from the unity serializer, which is really bad. The reason why enums cannot be displayed as enums in the inspector and passed in as integers lies deep within the UnityEvent deserialization of methods where it rejects methods that have more than one parameter or a parameter that is of a non-primitive type.

    Since I can't modify UnityEngine.dll and UnityEditor.dll, my options have been limited, but I've managed to come up with a solution. I've copied the UnityEditorInternal.UnityEventDrawer from the UnityEditor.dll assembly and made it into a new class which is used for UnityEvent instead of UnityBaseEvent, thus "overriding" the old. Then I display the integer argument as an enum popup based on an attribute. I'll post my solution with explanations in a second.
     
    AlonMixed and ugen_oak like this.
  48. llamagod

    llamagod

    Joined:
    Sep 27, 2015
    Posts:
    76
    This is my humble solution. Place the UnityEventDrawer in your Editor folder (Assets/Editor), place EnumActionAttribute anywhere you like. When there is a method with one enum argument you'd like to expose in the UnityEvent create a method taking in an integer argument and apply the EnumActionAttribute to it, passing in your enum type. If you do that the integer method will be available in the UnityEvent inspector, but now the argument will be shown as an enum dropdown. If you have any questions just ask. Here are two example implementations:
    Example 1:

    Code (CSharp):
    1. public class SomeClass : MonoBehaviour
    2. {
    3.     [EnumAction(typeof(SomeEnum))]
    4.     public void SomeMethod(int argument)
    5.     {
    6.         var enumArgument = (SomeEnum)argument;
    7.         // Implement method
    8.     }
    9. }
    Example 2:


    Code (CSharp):
    1. public class SomeClass : MonoBehaviour
    2. {
    3.     public void ActualMethod(SomeEnum argument)
    4.     {
    5.               // Implement method
    6.     }
    7.  
    8.     [EnumAction(typeof(SomeEnum))]
    9.     public void SomeMethod(int argument)
    10.     {
    11.         ActualMethod((SomeEnum)argument);
    12.     }
    13. }
     

    Attached Files:

  49. Ironmax

    Ironmax

    Joined:
    May 12, 2015
    Posts:
    890
    Enums in inspector works just fine.
     
  50. Daerst

    Daerst

    Joined:
    Jun 16, 2016
    Posts:
    275
    Much appreciated, sir! Works great, except for when you edit your enum. The property seems to store the index (to the list of enum values), rather than the actual int value of the enum. E.g. if you have an enum like this:

    Code (csharp):
    1. public enum GameState
    2. {
    3.   Intro = 0,
    4.   Playing = 50,
    5.   Paused = 100
    6. }
    and extend it like this:

    Code (csharp):
    1. public enum GameState
    2. {
    3.   Intro = 0,
    4.   Playing = 50,
    5.   MorePlaying,
    6.   Paused = 100
    7. }
    then any EnumAction that was pointing to Paused before will now point to MorePlaying, despite the explicit enum ID.

    Here is a modification of your original Popup that utilizes Unity's EnumPopup and stores the correct values:
    Code (csharp):
    1. // Make an enum popup
    2. var enumType = ((EnumActionAttribute)attributes[0]).enumType;
    3. Enum value = (Enum) Enum.ToObject(enumType, propertyRelative6.intValue);
    4. propertyRelative6.intValue = Convert.ToInt32(EditorGUI.EnumPopup(position3, value));
     
    Last edited: Sep 30, 2016
    issac8a, samuelchou, Bas-Smit and 2 others like this.