Exposing C# Properties in the Inspector

I know this has been asked many times in the past, but seriously, when will we ever see properties exposed in the editor?

I like to use properties over variables as I can execute logic when a value is changed. For example, if the Opacity value in my script is changed, it can automatically change the opacity of all images.

But since I’m forced to use variables, if I want a similar experience, I have to use the Update loop. This wouldn’t be a big deal if the value was being changed every second or so, but it is if the value will rarely be changed. It just seems to be a waste of performance.

float _opacity;
public float Opacity
{
    get => _opacity;
    set
    {
        _opacity = value;

        foreach (var image in images)
        {
            var colour = image.color;
            colour.a = Opacity;
            image.color = colour;
        }
    }
}

vs

[SerializeField] float opacity;
float previousOpacity;

void Update()
{
    if (Math.Abs(opacity - previousOpacity) > .01f)
    {
        previousOpacity = opacity;

        foreach (var image in images)
        {
            var colour = image.color;
            colour.a = opacity;
            image.color = colour;
        }
    }
}

vs a mix of both

[SerializeField] float _opacity;
public float Opacity
{
    get => _opacity;
    set
    {
        SetOpacity(value);
    }
}
float previousOpacity;

void Update()
{
#if UNITY_EDITOR
    if (Math.Abs(opacity - previousOpacity) > .01f)
        SetOpacity(opacity);
#endif
}

void SetOpacity(float opacity)
{
    _opacity = Opacity;
    previousOpacity = _opacity;

    foreach (var image in images)
    {
        var colour = image.color;
        colour.a = _opacity;
        image.color = colour;
    }
}

Correct me if I’m wrong, but you shouldn’t need to use an Update loop in this context.
If you have a setup like this, for instance…

[SerializeField] private int someVar;

public int SomeVar {
   get => someVar;
   set {
      someVar = value;
      SomeMethodWhenVarChanged();
   }
}

void SomeMethodWhenVarChanged() {
   //etc...
}

…Changing someVar in the inspector should still call the setter block in its property.

You can also sort-of serialize auto-properties as shown here, but it’s not exactly ideal since it uses the name of the auto-generated backing field, and the name cannot be changed.

I’d like to hopefully see that improved one day.

I usually do the #UNITY EDITOR define thing on the backing field like you showed. But yeah it would be nice. BTW, empty update methods do actually get called (unless they recently changed something, so you’re actually taking a performance hit with this:

void Update()
{
#if UNITY_EDITOR
    if (Math.Abs(opacity - previousOpacity) > .01f)
        SetOpacity(opacity);
#endif
}

vs this:

#if UNITY_EDITOR
void Update()
{
    if (Math.Abs(opacity - previousOpacity) > .01f)
        SetOpacity(opacity);
}
#endif

This seems completely impossible to me… is this true? How would Unity even know that someVar is a backing field for a particular property to call the setter?

Yeah, it doesn’t sound right to me either, but I swear I remember having a similar setup and it would actually work.
Maybe I’m remembering that wrong though. I can’t test it at the moment.

Edit:
Ah you know what, it was probably OnValidate that I was using.
That could be used instead of Update for this context.

1 Like

I don’t think this works. It’s a one-way relationship. someVar does not know anything about SomeVar.

OnValidate() does look interesting. I’ll probably give it a go in the future,