Download

How to achieve PostEditChangeProperty like behavior in-game insteadof in-editor mode?

I have a boolean UPROPERTY that is exposed on the actor’s detail panel. When I change this in the editor the actor’s OnConstruction function is invoked and the actor is reconstructed in the level taking that boolean into account.

I also added a PostEditChangeProperty to watch for changes in the property, hoping that I could use this to watch for changes to the property in-game (triggered via blueprints) but it turns out that PostEditChangeProperty is only called when you change details from within the Editor.

So two questions in all:

  1. How do I listen to property changes in-game, is there something like PostEditChangeProperty or a property setter accessor syntax that I’m missing? I realize I can just create a UFUNCTION and invoke that from blueprints instead (that’s what I’m doing now) so this is more of a design what-if question.

  2. What’s the point of using PostEditChangeProperty if the OnConstruction function gets reinvoked for all property changes in the details panel anyhow? Assuming the OnConstruction script constructs the object taking all UPROPERTY-ies into account won’t the effect of reacting to those property changes in PostEditChangeProperty be the same?

  1. There is no property keyword that automatically makes properties fire events like PostEditChangeProperty does. Simply create yourself a multicast delegate, poll the value in tick, and fire the delegate when it changes.

  2. Like the name says, OnConstruction is called when an actor finishes constructing. A lot of changes in the editor will incidentally cause this to happen, but not always. Also, as you’ve found out, PostEditChangeProperty only occurs in the editor, whereas OnConstruction occurs on all contexts. Lastly, OnConstruction is an Actor-specific override, whereas PostEditChangeProperty is on all UObjects.

It’s simply a matter of properly controlling scope – if you want one of your objects to be aware of a change to its properties in the editor, possibly to do validation or update a derived property, that’s what you would use PostEditChangeProperty for. If you want to do final updates on an actor once it is finishing construction, you would use OnConstruction. (Actually, most of the time you would want to use PostInitializeComponents, but that’s a different story.)

Thanks for the quick response, what you say makes sense.

As a side note, I’m also wondering what the best way would be to setup C# style GET/SET accessors within code. If it were all C++ one would write some plain old getter/setter syntax but with Blueprints and UPROPERTY variables in the mix it sounds like one would need a UFUNCTION GETTER and a UFUNCTION SETTER wrapping a private variable to simulate acessors that would also work from Blueprints right? (that does seem rather wasteful, although I’m just curious to see how others have approached this just from a design sense rather than practical functionality)

When exposing a UPROPERTY to blueprint, it already creates accessors of sorts. BlueprintReadOnly will create a getter, BlueprintReadWrite will also create a setter. The only cases where I would manually define blueprint accessors is in the case of non-trivial ones, i.e.: if I need to convert, reformat or otherwise massage the data before getting/storing it.

For native, most of the time, a BlueprintReadOnly property is also meant to be encapsulated in C++. In that case, I keep it protected/private and create a native GetMyProperty getter. BlueprintReadWrite properties I usually just expose directly, unless I think I might need non-trivial accessors later on. Unlike C#, you can’t directly substitute a field access to a function call in C++, so it can be troublesome going through lots of direct field accesses to figure out which ones will need to become a SetMyProperty and which will be GetMyProperty.

Thanks again for the insight.