How to get my properties to show up in a UnityEvent handler?

Many of the built-in components have public properties that you can set from a UnityEvent handler. For example, AudioSource.volume is one of these.

But if I make my own public property, e.g. “public float volumeFactor”, it does not show up among the things I can set when I hook it up to a UnityEvent.

I suspect there is an attribute I have to specify, but nothing in the docs looks very promising. I tried SerializeField and a few others anyway, but they had no effect.

Anybody know how I can get my own custom properties to be settable in an event handler?

Isnt the event stuff open source? Couldnt you check through that? I guess it is an attribute to. Or some reflection magic the editor is doing.

Properties aren’t allowed to be scene in the inspector unless you’re in Debug mode. You can always created a private field and serialize it and then use the property to control the read/write settings.

Wait, is it? Where would I find the source for it?

What? Public properties are always seen in the inspector (unless you add the HideInInspector attribute). And I’m afraid I don’t understand your second sentence at all.

I can work around this by creating a public setter method which I invoke from an event, of course, but that gets old fast. I’d much rather just set the public properties directly, as we can do with built-in components.

I think SubZeroGaming means properties in the correct defintion (with the get{} and set{}) not public variables. He is right about that properties, as in the C# definition wont appear in the editor - public variables will though

UI source: https://bitbucket.org/Unity-Technologies/ui

public fields are seen in the inspector. Not properties. I think you have the definition of a property confused.

1 Like

Ah yes, I see what you mean now. You’re right, I should have said field rather than property.

@Komo, thanks for the pointer to the UI source… I’ll comb through it and see what I can find!

Well, I finally dug up the source (now here), and found the answer, and it’s a bit suprising:

The Unity event drawer will allow you to set properties but not plain fields.

This is because, it turns out, the whole event system is built around invoking methods, and has no support for fields at all. Those things that you can assign a value to directly from an event are things that have a setter method, and it’s because they have a setter method that they are easily hooked into the event system.

One can imagine a more sophisticated event system that would have support for fields as well, but Unity Event is not such a system.

So, mystery solved… and it only took me 6 years to get annoyed enough to actually go dig up the answer. :slight_smile:

5 Likes

@JoeStrout

I just add the attribute:

[field: SerializeProperty] and make sure the property is a {get; set:}

That will expose the property to the UnityEvent system without writing any boilerplate methods.

In Unity versions before 2021 you will get visual weirdness in the inspector label, and even in current versions the label will always be in pascalCase instead of the usual CamelCase unless you make the property in PascalCase or prefixed by an underscore from the start.

Label aside it is quite convenient.