Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  6. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  7. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  8. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Multiple Attributes

Discussion in 'Extensions & OnGUI' started by BinaryCats, Feb 22, 2016.

  1. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    126
    Is it possible to know if a variable has multiple attributes, and what they are, from the drawer?


    --

    Case:
    I have an attribute called ReadOnly, This attribute disallows editing in the inspector.
    example code: http://answers.unity3d.com/questions/489942/how-to-make-a-readonly-property-in-inspector.html

    However, using ReadOnly on a variable which also uses the Range(...) attribute does not work. What happens is the variable is rendered in the inspector like a normal (read only) float and not like a Range attributed float.

    I would like to know what attributes are currently on the variable I am drawing (in the property drawer) so I can deal with them accordingly.
     
    Last edited: Mar 24, 2016
  2. skalev

    skalev

    Joined:
    Feb 16, 2012
    Posts:
    264
  3. MrMatthias

    MrMatthias

    Joined:
    Sep 18, 2012
    Posts:
    97
    you can do this with reflection:
    Code (CSharp):
    1. using System.Reflection;
    2. ...
    3.  
    4. FieldInfo[] fields = this.GetType ().GetFields (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    5. foreach (FieldInfo field in fields) {
    6.     object[] attributes = field.GetCustomAttributes (true);
    7. }
     
    jj_unity328 likes this.
  4. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    126
    Thanks for the reply, However, im not sure if you are barking up the wrong tree, or maybe I don't understand how to use that code.

    I Tried, to use your code, in my attribute's drawer, and discovered that the fields it got was the fields in that class. I don't want this, I want to get the field that the property is being drawn from and check it's attribute.

    This is the case I want to do this, ill update the OP as well.

    I have an attribute called ReadOnly, This attribute disallows editing in the inspector.
    example code: http://answers.unity3d.com/questions/489942/how-to-make-a-readonly-property-in-inspector.html

    However, using ReadOnly on a variable which also uses the Range(...) attribute does not work. What happens is the variable is rendered in the inspector like a normal (read only) float and not like a Range attributed float.

    I would like to know what attributes are currently on the variable I am drawing (in the property drawer) so I can deal with them accordingly.

    Thanks
     
  5. MaximusLitvinov

    MaximusLitvinov

    Joined:
    Jan 27, 2017
    Posts:
    1
    Hello I am having the same problem. Were you ever able to solve this issue?

    Thank you!
     
  6. TrickyHandz

    TrickyHandz

    Joined:
    Jul 23, 2010
    Posts:
    194
    @MaximusLitvinov The problem here is that you can't have 2 different PropertyDrawers for the same field. Unity will only use the first PropertyDrawer and ignore all others.
     
    Ash-Blue likes this.
  7. jj_unity328

    jj_unity328

    Joined:
    Jun 7, 2018
    Posts:
    18
    From a `SerializedProperty`, you can find the associated `FieldInfo` ( http://answers.unity.com/answers/1347452/view.html ) then use `GetCustomAttributes` or `GetCustomAttribue<YourAttribute>` if you're only looking for a specific one.

    If it doesn't return null, you know this other attribute is there too and you can call its drawer's GUI.

    Code (CSharp):
    1. public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    2. {
    3.     // Do stuff before and/or after this if desired
    4.     if(HasAttr<MyAttr>(property))
    5.          new MyDrawer().OnGUI(position, property, label);
    6. }
    7.  
    8. private static bool HasAttr<T>(SerializedProperty property) where T: Attribute
    9. {
    10.     // Inspired by http://answers.unity.com/answers/1347452/view.html
    11.     // and https://forum.unity.com/threads/multiple-attributes.387515/#post-2566777
    12.     Type parentType = property.serializedObject.targetObject.GetType();
    13.     FieldInfo fi = parentType.GetField(property.propertyPath, BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    14.     // fi is sometimes null for reasons I ignore but it still seems to work
    15.     return fi?.GetCustomAttribute<T>() != null;
    16. }
    @TrickyHandz You can if you call one GUI from the other.
     
    Last edited: Jul 30, 2018