Search Unity

how to use custom PropertyAttribute without causing build errors?

Discussion in 'Immediate Mode GUI (IMGUI)' started by JoeStrout, Apr 22, 2017.

  1. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    I'm trying to make a simple attribute I can attach to properties to add a pop-up list of options. This consists of a custom PropertyAttribute and a custom PropertyDrawer. I initially had my PropertyDrawer subclass in an "Editor" folder, and the PropertyAttribute not.

    All works great in the IDE, but when I tried to build, it barfed because PropertyAttribute is defined in UnityEngine, which isn't available in builds.

    OK then, I moved my PropertyAttribute into an Editor folder as well. But now it barfs everywhere I try to use this custom attribute, because the custom attribute can't be found.

    It seems like I'm damned if I do, and damned if I don't... how should I properly arrange my files so that I can define these custom attributes to be used in the editor, and still be able to build?
     
  2. Johannski

    Johannski

    Joined:
    Jan 25, 2014
    Posts:
    826
    Your initial setup is correct: PropertyAttribute in normal folder, PropertyDrawer in Editor folder.

    Do you maybe import UnityEditor in your PropertyAttirbute ( using UnityEditor; )? This would not be allowed in builds.

    Here is a small example for an Attribute and drawer:

    UnitAttribute.cs
    Code (CSharp):
    1. using UnityEngine;
    2. /// <summary>
    3. /// Put this attribute above any field
    4. /// It adds a small label to the right of the property field.
    5. /// This small label can be used to add information about the assumed unit.
    6. ///
    7. /// <code>
    8. /// <para>[Unit("m/s²")]</para>
    9. /// <para>public float gravity = 9.80665f;</para>
    10. /// </code>
    11. /// </summary>
    12. [System.AttributeUsage(System.AttributeTargets.Field, AllowMultiple = true)]
    13. public class UnitAttribute : PropertyAttribute
    14. {
    15.      public string label;
    16.      public GUIStyle labelStyle;
    17.      public float width;
    18.  
    19.      public UnitAttribute( string label )
    20.      {
    21.          this.label = label;
    22.          labelStyle = GUI.skin.GetStyle("miniLabel");
    23.          width = labelStyle.CalcSize(new GUIContent(label)).x;
    24.      }
    25. }
    26.  
    UnitAttributeDrawer.cs (In Editor folder)
    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3.  
    4. namespace BitStrap
    5. {
    6.     [CustomPropertyDrawer(typeof(UnitAttribute))]
    7.     public class UnitAttributeDrawer : PropertyDrawer
    8.     {
    9.         public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    10.         {
    11.             UnitAttribute labelAttribute = attribute as UnitAttribute;
    12.             EditorGUI.PropertyField(position, property, label);
    13.             GUI.Label(position.Right(labelAttribute.width + 2f), labelAttribute.label, labelAttribute.labelStyle);
    14.         }
    15.     }
    16. }
     
    Last edited: Feb 27, 2024
    Kokowolo, Alobal17, brainwipe and 8 others like this.
  3. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    Ah, you're right. I was under the mistaken belief that PropertyAttribute was in UnityEditor rather than UnityEngine. It's not, so removing the "using UnityEditor" was all that was required.
     
  4. paul-masri-stone

    paul-masri-stone

    Joined:
    Mar 23, 2020
    Posts:
    49
    Apologies for necro. A point of clarity (that may be obvious to some, but wasn't to me).

    Note that the UnitAttribute file needs to include
    using UnityEngine;
    as
    PropertyAttribute
    is in this namespace.
     
    mcroswell likes this.
  5. HofiOne

    HofiOne

    Joined:
    Apr 19, 2021
    Posts:
    68
    Just for the record, probably someone will get into this too.

    I had a similar layout described above and tried exactly the same sample like the above too, but I could not get this work, my custom Drawer always missed my custom PropertyAttribute

    I guess, in my case, the problem was that my Editor (where my custom drawer resides) folder is under my Scripts folder (where my custom PropertyAttribute can be found).

    The only solution I could find was to add a symlink to the custom PropertyAttribute file in the Editor folder of the custom Drawer.

    (This happens on macOS 13.1 ARM and Unity 2021.1.28)
     
  6. HofiOne

    HofiOne

    Joined:
    Apr 19, 2021
    Posts:
    68
    and of course, it was my fault
    i'm using various assembly definitions and forgot to add the assembly reference of the custom PropertyAttribute container assembly to the Drawer container Editor assembly definition
    hope this will help someone once