Home > Blockchain >  Unity PropertyAttribute, interfering with other PropertyAttributes
Unity PropertyAttribute, interfering with other PropertyAttributes

Time:11-17

I have an Attribute

public class LockAttribute : PropertyAttribute { }

with a custom drawer script

[CustomPropertyDrawer(typeof(LockAttribute))]
public class LockAttributePropertyDrawer : PropertyDrawer 
{
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        EditorGUI.BeginDisabledGroup(Application.isPlaying);
        _= EditorGUI.PropertyField(position, property, label);
        EditorGUI.EndDisabledGroup();
    }
}

it's purpose is to disable the inspector field when the application is playing.

If I use it in this order

[SerializeField,Range(0,100),Lock] private int m_Resolution;

the field never disables, and when I swap the Range and Lock attributes, the Range attribute has no effect.

Is there a way to have both attributes take effect?

I attempted using

Base.OnGUI(position, property, label);

instead of

EditorGUI.PropertyField(position, property, label);

but doing so resulting in No GUI Implmented appearing over my fields`.

CodePudding user response:

Looks like a "bug" in Unity 2020.3.

It works for me if I simply invert the order (Unity 2021.2.2f1):

[SerializeField] 
[Lock]
[Range(0, 100)]
private int m_Resolution;

Alternatively you can also add the order parameter like

[SerializeField] 
[Range(0, 100, order = 1)]
[Lock(order = 0)]
private int m_Resolution;

though I would prefer to rather simply have them in the correct order right away ^^

enter image description here


My general Guess: The reason is that in this case you first add the disabled group, then let the PropertyField handle any other drawers added later that internally might not be using PropertyField but rather direct value drawers. If you have the Range first, however, it already overwrites the drawer completely with direct value fields (the slider) and doesn't further forward the draw call via a PropertyField so no later attribute drawers are handled anymore.


So long story short: Unfortunately multiple attributes are always quite tricky and most of them are not able to be combined or at least like in this case the order matters a lot!

For example even though the [Min] attributes on first glance doesn't change the appearance of an int field, still your [Lock] needs to go first, otherwise it is ignored.

And there is e.g. no way at all to combine [Range] and [Min] regardless the order.

=> For those cases you would need to go and write a new combined attribute and drawer yourself!

  • Related