Search Unity

  1. New Unity Live Help updates. Check them out here!

    Dismiss Notice

Ability to add enum argument to button functions

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

  1. Romaleks360

    Romaleks360

    Joined:
    Sep 9, 2017
    Posts:
    34
  2. huulong

    huulong

    Joined:
    Jul 1, 2013
    Posts:
    57
    I'm using @llamagod 's solution, which works fine, but I'm worried about the fact that UnityEventDrawer.cs is taken from Unity source code and adds a patch in the middle of the DrawEventListener function...

    See original code on GitHub

    This code looks slighty different because:
    - llamagod is using a reverse-engineered version
    - the code has changed with the iterations for 2017, 2018, etc.
    - we must use properties and reflection to access private/internal members

    When Unity is upgraded, the original code will go further and further from our custom implementation. In the best case we'll lost some extra features and fixes from new versions, in the worst case compatibility will break and the project will stop compiling (in the editor).

    For now, I will copy-paste the patch (including reflection usage) inside the code that matches my version of Unity, but I wonder if there is not a solution involving overriding some nice method...
    Like setting a custom drawer for some IntAsEnum field, which would be used by PropertyField.

    The patching part:

    Code (CSharp):
    1.  
    2.             // Try to find Find the EnumActionAttribute
    3.             var method = GetMethod(m_DummyEvent, methodName.stringValue, listenerTarget.objectReferenceValue, GetMode(mode), desiredType);
    4.             object[] attributes = null;
    5.             if (method != null)
    6.                 attributes = method.GetCustomAttributes(typeof(EnumActionAttribute), true);
    7.             if (attributes != null && attributes.Length > 0)
    8.             {
    9.                 // Make an enum popup
    10.                 var enumType = ((EnumActionAttribute)attributes[0]).enumType;
    11.                 var value = (Enum)Enum.ToObject(enumType, argument.intValue);
    12.                 argument.intValue = Convert.ToInt32(EditorGUI.EnumPopup(argRect, value));
    13.             }
    14.             else
    15.             {
    16.                 EditorGUI.PropertyField(argRect, argument, GUIContent.none);
    17.             }
    18.  
    Also, don't forget to make the CustomPropertyDrawer work on `typeof(UnityEvent)`, not `typeof(UnityEventBase)`


    The history of my file to understand how I re-applied the patch from the released Unity code:
    https://github.com/hsandt/LD44/commits/master/Assets/Game/Scripts/Editor/UnityEventDrawer.cs
     
  3. llamagod

    llamagod

    Joined:
    Sep 27, 2015
    Posts:
    76
    @huulong Yes, your observations and concerns are valid. This is a hack. To my knowledge, this is about as good as it's going to get without being able to modify the Unity source code as an employee or overhauling the editor serialization system and inspector. I only really changed DrawEventListener, but it's a big method and it's private and it's called by another private method so it cannot be overridden without some serious reflection and low-level programming magic.

    The reason why I use typeof(UnityEventBase) is that I have to go a step up in the inheritance hierarchy such that my custom drawer will be picked for UnityEvent instead of the built-in Unity one. I can't think of any problems this could create.

    A proper fix for issues like this would require overhauling the editor serialization system and inspector. I don't know the internal workflow of Unity staff. But having attempted something like this before (also attempted by others, for example, https://assetstore.unity.com/packages/tools/utilities/odin-inspector-and-serializer-89041), I'm guessing this would take Unity 4 to 6 months for a small team dedicated to it (keep in mind this is for a brilliantly crafted solution that looks nice and is refactored many times and includes very thorough testing).
     
    Last edited: May 17, 2019
  4. fluffycritter

    fluffycritter

    Joined:
    Jun 2, 2019
    Posts:
    1
    I just want to thank you for posting this solution; I just tried it out and it works wonderfully. It'd be great if Unity were to fix it in the editor themselves but it's not all that onerous to use this workaround.
     
  5. JeevSiewnath

    JeevSiewnath

    Joined:
    Dec 31, 2013
    Posts:
    1
    Ridiculous, 2019 and still waiting for this basic functionality...
     
  6. Rathlord

    Rathlord

    Joined:
    Oct 13, 2013
    Posts:
    16
    C'mon Unity team we'd really love to have this...
     
  7. llamagod

    llamagod

    Joined:
    Sep 27, 2015
    Posts:
    76
    If you look at the Unity roadmap for 2019.3.0 "Polymorphic Serialization" is there which means they will have fixed the serialization system at that point. So I'm guessing this feature will be added relatively soon after, maybe 2020.
     
    leni8ec likes this.
  8. Letail

    Letail

    Joined:
    May 22, 2017
    Posts:
    10
    Just found out this isn't a feature. Please implement it!
     
    tarahugger likes this.
  9. tarahugger

    tarahugger

    Joined:
    Jul 18, 2014
    Posts:
    120
    You've got to be kidding me... We still can't select an enum value from a button click? :mad:
     
  10. Braza

    Braza

    Joined:
    Oct 11, 2013
    Posts:
    94
    Meh... A bump from me. Surprised it is not there.
     
  11. Hassurunous

    Hassurunous

    Joined:
    Apr 6, 2017
    Posts:
    5
    Another humble bump. I realize there are underlying complexities that make this more difficult than just "turn it on", but man it would make sense and would make my life easier.
     
  12. achimmihca

    achimmihca

    Joined:
    Feb 13, 2016
    Posts:
    18
    I agree. Useful feature, old thread, should be implemented. Also note that you can already select enum values for public variables from a drop-down. I would expect the same drop down to select the value for the parameter of a callback function.
     
  13. Zecrah

    Zecrah

    Joined:
    Nov 1, 2016
    Posts:
    1
    +1 for this
     
  14. justincywong12

    justincywong12

    Joined:
    Feb 15, 2019
    Posts:
    1
    Hey this is a workaround that I've found works. It has a fail-safe incase you make an error in your string input

    if( System.Enum.TryParse<YourEnumType>(yourString, out YourEnumType yourEnum)
    {
    //use yourEnum to set your desired enum to the string input
    }
    else
    {
    Debug.LogWarning("Error in enum conversion");
    }
     
  15. achimmihca

    achimmihca

    Joined:
    Feb 13, 2016
    Posts:
    18
    The workaround I use is to have a Holder class, which only has a public field to set the enum value. You then create one instance of this class for every value of the enum (collect these instances in a prefab so you can reuse all values across different scenes). Afterwards you write your callback such that it accepts an instance of the holder class instead of the enum.

    Example:
    Code (CSharp):
    1. public class SceneEnumHolder : MonoBehaviour
    2. {
    3.     public EScene scene;
    4. }
    Code (CSharp):
    1. public void OnButtonClicked(SceneEnumHolder holder)
    2. {
    3.     Debug.Log("you are in scene "+holder.scene);
    4. }
     
  16. PitaBreadGames

    PitaBreadGames

    Joined:
    Sep 15, 2017
    Posts:
    1
    Humble Bump
     
  17. alternative_richie

    alternative_richie

    Joined:
    Sep 4, 2014
    Posts:
    14
    @llamagod Thanks for your solution! Nice....
     
  18. ponos_sanchez

    ponos_sanchez

    Joined:
    Aug 16, 2017
    Posts:
    2
    This need implement ASAP in the editor. It's a basic function.
    Any progress Unity team?
     
  19. JohnHudeski

    JohnHudeski

    Joined:
    Nov 18, 2017
    Posts:
    126
    Are you kidding me?
    5 Years later
     
  20. alexsyo

    alexsyo

    Joined:
    May 1, 2016
    Posts:
    1
    Is there any progress on the implementation from the Unity team?
    .. or better any progress on taking this into consideration...
     
  21. Sparkline

    Sparkline

    Joined:
    Feb 8, 2013
    Posts:
    81
    5 years ago I had to froze my project until this feature will come out. Since that time I became father and got a child (son 3.5 years old now). Just checked this thread, still no implementation... uh...ok!
     
    neilsarkar likes this.
  22. gino_pisello

    gino_pisello

    Joined:
    Jun 24, 2013
    Posts:
    28
    I've not been here since 2014, but I need this feature too
     
  23. wpetillo

    wpetillo

    Joined:
    May 23, 2017
    Posts:
    7
    +1 because this would be a nice feature to have for buttons, +10 because the same issue applies to UnityEvents more generally (which are one of Unity's best and underused features), +100 because it reflects an underlying technical debt issue in the engine.
     
    Cogniad and leni8ec like this.
  24. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    67
  25. rsodre

    rsodre

    Joined:
    May 9, 2012
    Posts:
    199
    I took it for granted, was puzzled of why methods with enum parameters were not showing in event lists.
    Then I found this thread...
    :eek::eek::eek:
     
  26. unity_3luka1

    unity_3luka1

    Joined:
    Feb 3, 2020
    Posts:
    1
    Are you kidding me Unity? What is this crap
     
  27. Planet11

    Planet11

    Joined:
    Nov 3, 2011
    Posts:
    22
    llamagod, I just tried using your workaround in 2019.3.0f3

    I'm getting a null reference in UnityEventDrawer at the line:
    var type = Type.GetType(prop.FindPropertyRelative("m_TypeName").stringValue, false);
    and no events at all are appearing in the inspector on any buttons. (toggles are fine)

    Reverting it now, I'm not sure, but I think most likely it is because I tried using it on a toggle, hoping to see an enum in an OnValueChanged Event rather than a button's OnClick, anyway just thought I'd give you a heads up that I managed to break it.

    Thanks very much for the workaround by the way, it's appreciated.

    In case you're wondering why anyone would need an enum on a toggle, they're a group of category filters so I can toggle all the weapons, or all the engines etc.
     
  28. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    67
    Guys, the workaround didn't work for me either

    but this works, try it!

    https://assetstore.unity.com/packag...10.681738839.1581068424-1078625206.1576573019
     
    Last edited: Feb 12, 2020
  29. Planet11

    Planet11

    Joined:
    Nov 3, 2011
    Posts:
    22
    I couldn't get the workaround going after removing the toggles, could be that it's broken in 2019.3?
    I ended up just ditching the button component and writing a tiny replacement button class that takes a specific enum from an unrelated class and hands it along, so it's not reusable but it does the job.
     
  30. Simon-O

    Simon-O

    Joined:
    Jan 22, 2014
    Posts:
    34
    Five and a half years, and still no progress.
     
  31. mbshaikh19

    mbshaikh19

    Joined:
    Mar 27, 2017
    Posts:
    2
    At least now I know, its not possible in Unity.
     
  32. haywirephoenix

    haywirephoenix

    Joined:
    May 17, 2017
    Posts:
    67
    https://assetstore.unity.com/packag...10.681738839.1581068424-1078625206.1576573019
     
  33. neilsarkar

    neilsarkar

    Joined:
    Aug 11, 2017
    Posts:
    3
    +1 would use this feature
     
unityunity