Custom Event Drawer for Generic Events get overridden by odin

Issue #281 resolved
Duncan Waterreus created an issue

My specific use case is where I try to change the drawer for a given parameter type (int or Enum), based on an attribute placed on the target method (in this case Enum dropdown and an int that is displayed as a drop down created from an array of strings (the value is the selected index)), basic things Unity sorely needs to make things user friendly.

[CustomPropertyDrawer(typeof(UnityEvent), true)] works like a charm, both types work

However, these do not work, unless I disable Odin in editor: [CustomPropertyDrawer(typeof(UnityEventBase), true)] [CustomPropertyDrawer(typeof(BoolEvent), true)] [CustomPropertyDrawer(typeof(UnityEvent<bool>), true)] [CustomPropertyDrawer(typeof(UnityEvent<Boolean>), true)] [CustomPropertyDrawer(typeof(IntEvent), true)] [CustomPropertyDrawer(typeof(FloatEvent), true)] [CustomPropertyDrawer(typeof(StringEvent), true)] [CustomPropertyDrawer(typeof(Vector3Event), true)] [CustomPropertyDrawer(typeof(ScorePositionEvent), true)] public class UnityEventDrawer : PropertyDrawer {}

(in 1.0.5.9 it would show a lot of errors when using this name, changing it to CustomUnityEventDrawer did solve those errors), not sure if either type worked ( I haven't checked since the update to 1.0.6.0)

DrawerPriority and ShowDrawerchain were of no help to remedy this inconveniance. DrawWithUnity is not usable with a custom property drawer.

OdinDrawer / OdinPropertyDrawer is of no use, as I could not get it to work at all in combination with the generic UnityEvent<> or UnityEventBase.

using Odin 1.0.6.0 it would be solved if we could either: prevent odin from serializing events or, use odin to draw a specific drawer for events.

The events in question are also decorated with things like FoldoutGroup, but are unrelated to the issue.

As I do not have access to all the events, a custom specific drawer for each event is undesirable. Also I would prefer to get a generic implementation (I only care about it being a parameter set to attributed function/method).

I based the initial CustomUnityEventDrawer on: https://forum.unity.com/threads/ability-to-add-enum-argument-to-button-functions.270817/#post-2785739

Comments (6)

  1. Bjarke Elias

    Interesting drawer through.

    But you've hit kind of an edge case with Odin, We do a lot of really weird stuff in order to make Unity Events work in Odin Serialized contexts. But maybe we can make it work out of the box somehow. I'll leave this Open for Tor when he comes back.

    For now, you can easily tell Odin to draw UnityEventBases with Unity. We do this as well with Gradients and AnimationCurves.

    [OdinDrawer]
    public class DrawUnityEventsWithUnity<T> : DrawWithUnityBaseDrawer<T>
        where T : UnityEventBase
    {
    }
    
  2. Bjarke Elias

    Do note that it will not work if you're serializing the UnityEvents with Odin, as you would be overriding our drawer trickery that makes it work. If you're serializing it using Odin, I would suggest serializing delegates instead.

    public class SomeComponent : SerializedMonoBehaviour
    {
        public MyEvent<SomeEnum> test;
    
        public void SomeMethod(SomeEnum test)
        {
    
        }
    }
    
    [InlineProperty(LabelWidth = 50)]
    public struct MyEvent<T>
    {
        [SerializeField]
        private T arg1;
    
        [SerializeField, HideLabel]
        private Action<T> action;
    
        public void Invoke()
        {
            this.action(this.arg1);
        }
    }
    
  3. Duncan Waterreus reporter

    [OdinDrawer] public class DrawUnityEventsWithUnity<T> : DrawWithUnityBaseDrawer<T> where T : UnityEventBase { }

    Works perfectly, thanks for the quick work-around

  4. Tor Esa Vestergaard

    Putting [DrawerPriority(0, 0, 1)] on the custom event drawer definitely works in Odin 2.0+ (I have just verified this), so I will mark this issue as resolved.

  5. Log in to comment