Search Unity

Using property fields in custom editor when using auto-properties?

Discussion in 'Scripting' started by Ardenian, Feb 14, 2020.

  1. Ardenian

    Ardenian

    Joined:
    Dec 7, 2016
    Posts:
    313
    I use the neat trick using the field-keyword to write my class definitions like this:

    Code (CSharp):
    1. public class MyFloatVariable : ScriptableObject
    2. {
    3.     [field:SerializeField]
    4.     public float Value { get; private set; }
    5. }
    6.  
    However, while writing a custom editor for my
    MyFloatVariable
    class, I noticed that it doesn't find the properties when using
    SerializedProperty value = serializedObject.FindProperty("Value");
    , resulting in
    null
    references.

    Is there any way to make this work with auto-properties? I could swear that I saw a solution for this somewhere on the forums, but as always, searching for it yielded little to no results. I mean, since Unity does serialize the fields behind the properties, there got to be a way to reference them, no?
     
  2. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    It's because FindProperty expects the name of the underlying field, and not the name of the property. Because the field is what is serialized, not the property (hence you're need to do [field:SerializedProperty]).

    The field name is going to be formatted like (as long as the compiler follows standard C# rules, which I'm pretty sure Unity's compiler does):
    <Value>k__BackingField

    If you loop all of the SerializedProperties of the SerializeObject and print out the names you'll see this.

    What I'd do is create an extension method... something like:
    Code (csharp):
    1.  
    2. public static SerializedProperty FindPropertyByAutoPropertyName(this SerializedObject obj, string propName)
    3. {
    4.     return obj.FindProperty(string.Format("<{0}>k__BackingField", propName));
    5. }
    6.  
     
  3. Ardenian

    Ardenian

    Joined:
    Dec 7, 2016
    Posts:
    313
    Thank you very much, @lordofduct, works like a charm!

    Not sure if I want to write a custom editor for every single class definition using auto-properties to get rid of the ugly name in the editor, but oh well. Do you happen to know if there is any downside to using auto-properties this way?
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,532
    If you're trying to create an editor that draws the property name correctly. You can create a custom attribute and a propertydrawer that does it for you. Then you just attribute the property like you did with SerializedField (using the field).

    https://docs.unity3d.com/ScriptReference/PropertyDrawer.html

    Follow the tutorial in there that does a 'RangeAttribute'. You'll just do it as a 'AutoPropertyAttribute'.

    Here is someone who wrote one where you can change the name to whatever you want:
    https://answers.unity.com/questions/1005277/can-i-change-variable-name-on-inspector.html

    ...

    As for if it'll be a problem... ehhh. It's a little "magical", which would spook me. Especially if for whatever reason the compiler changes up what it names the backing field (who knows, maybe one day you compile to some random platform and stuff blows up).

    Furthermore, if you rename the property down the line. You again have to be careful as the 'FormerlySerializedAs' attribute needs to take in the correct backing field name.

    Basically... it screams maintenance nightmare to me. Something you have to be aware of the inner-workings of C# for. Which can be a huge problem if you're on a team of devs of varying skill level.
     
    Ardenian likes this.
  5. Ardenian

    Ardenian

    Joined:
    Dec 7, 2016
    Posts:
    313
    Thank you for pointing me there! I have collected a little bit experience with custom editors and have yet to touch PropertyDrawers. They appear to be amazingly powerful, from what I have seen. ReadOnlyAttribute for properties in the inspector is a popular example, I would say.
    That's a very good point. Hm, I mean, in the end, auto-properties are only a short-cut and there is little damage in going the full way and separating field and property instead of using an auto-property. The examples that you pointed out scare me enough to consider dropping auto-properties alltogether. Thanks again!