A Unity ID allows you to buy and/or subscribe to Unity products and services, shop in the Asset Store and participate
in the Unity community.
Discussion in 'Unity UI (uGUI) & TextMesh Pro' started by Slev, Sep 26, 2014.
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:
// Try to find Find the EnumActionAttribute
var method = GetMethod(m_DummyEvent, methodName.stringValue, listenerTarget.objectReferenceValue, GetMode(mode), desiredType);
object attributes = null;
if (method != null)
attributes = method.GetCustomAttributes(typeof(EnumActionAttribute), true);
if (attributes != null && attributes.Length > 0)
// Make an enum popup
var enumType = ((EnumActionAttribute)attributes).enumType;
var value = (Enum)Enum.ToObject(enumType, argument.intValue);
argument.intValue = Convert.ToInt32(EditorGUI.EnumPopup(argRect, value));
EditorGUI.PropertyField(argRect, argument, GUIContent.none);
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:
@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).
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.
Ridiculous, 2019 and still waiting for this basic functionality...
C'mon Unity team we'd really love to have this...
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.
Just found out this isn't a feature. Please implement it!
You've got to be kidding me... We still can't select an enum value from a button click?
Meh... A bump from me. Surprised it is not there.
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.
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.
+1 for this
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
Debug.LogWarning("Error in enum conversion");
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.
public class SceneEnumHolder : MonoBehaviour
public EScene scene;
public void OnButtonClicked(SceneEnumHolder holder)
Debug.Log("you are in scene "+holder.scene);
@llamagod Thanks for your solution! Nice....
This need implement ASAP in the editor. It's a basic function.
Any progress Unity team?
Are you kidding me?
5 Years later
Is there any progress on the implementation from the Unity team?
.. or better any progress on taking this into consideration...
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!
I've not been here since 2014, but I need this feature too
+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.
I took it for granted, was puzzled of why methods with enum parameters were not showing in event lists.
Then I found this thread...
Are you kidding me Unity? What is this crap
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.
Guys, the workaround didn't work for me either
but this works, try it!
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.
Five and a half years, and still no progress.