AActor::PostEditMove checks if the Actor is a blueprint class before calling RerunConstructionScripts:
UBlueprint* Blueprint = Cast<UBlueprint>(GetClass()->ClassGeneratedBy);
if(Blueprint && (Blueprint->bRunConstructionScriptOnDrag || bFinished) && !FLevelUtils::IsMovingLevel() )
FNavigationLockContext NavLock(GetWorld(), ENavigationLockReason::AllowUnregister);
However, PostEditChangeProperty does not.
Is this intentional? if so, why? It creates a point of inconsistency between native classes that implement OnConstruction as a “C++ Construction Script” and Blueprint classes implementing a construction script - moving the former won’t call OnConstruction, but moving the latter will.
There is no particularly good reason. I traced the history back to CL #1588321 which added a feature for blueprints, but in the process stopped it from being called for native actors.
Changing it to something like if (Blueprint == nullptr || Blueprint->bRunConstructionScriptOnDrag || bFinished) should work (I moved the !FLevelUtils::IsMovingLevel() in to the if above for convenience). This would get the behavior back to what it was prior to the bRunConstructionScriptOnDrag change.
The alternative would be if (bFinished || (Blueprint && Blueprint->bRunConstructionScriptOnDrag)). That would reduce the potential overhead of the native construction script running every frame similar to how we don’t do a number of kinds of changes to avoid hitching while dragging.
I’ll need to talk to a few people to decide which of those two options we will go with, but to answer your actual question … no there is no good reason.
Thanks for pointing this out and we’ll get it fixed up.