Validating UPROPERTY changes in editor (in general)

In this question, I wondered how to force a particular TSubclassOf<> UPROPERTY to be non-None. It turned out there was a particular keyword which specifically selected that behavior, so hooray for that.

But more in general, I’m often running into situations where setting a particular UObject property in the editor should be validated/handled in some way. Certain validation behaviors have associated metadata types (think ClampMin/Max, NoElementDuplicate, etc., but there isn’t always one which fits.

What I’d like, basically, is some way of custom-validating property changes which happen in the editor. UObject::PostEditChangeProperty is tantalizingly close to fitting the bill, except that when it fires, the change has already been made, and there’s no way to find out what the old value was, so it can’t be reverted. (Similarly, PreEditChange happens too soon; there’s no way to know what the new value will be).

One option might be to instantly undo the change from PostEditChangeProperty… but initiating an undo from within a notification callback sounds dangerous, and I’m not actually sure how to go about it.

You can achieve this using Details Customizations (link a bit out of date but there are loads of examples in the engine source). It gives you total control, but unfortunately is kind of heavy. I agree it would be much nicer if it was possible to do proper property validation through PostEditChangeProperty, but like you I have not found a way to do so when you need to know the previous value.

That said, the codebase is huge so it’s possible this can be done more concisely than with Details Customizations and it just needs documenting…

For anyone stumbling on this old thread, check out UObject::IsDataValid. There’s an example of it from the engine in UInputAction::IsDataValid (for validating Enhanced Input actions).