Download

How to detect changes on UPROPERTY referenced objects?

Hi,

is there any way to detect changes on objects referenced by UPROPERTY? What I mean is for example I have UPROPERTY picker for a StaticMeshActor in a level or a Material. I have my own custom C++ class which places some instances on top of the static mesh. I would like to somehow detect when user moves the target StaticMeshActor and call some function in my C++ class to move instances to new, updated position. I am also placing instances based on some material properties, so I would like to detect when the Material asset has changed, and again call something on my C++ class to refresh the changes. Right now, the UPROPERTY only updates when I swap the assets, but that’s it.

I’d assume there is some kind of notification system which broadcasts editor changes, but I could not find anything about that. Closest I got to it were some kind of “delegates” FEditorDelegates | Unreal Engine Documentation but when I dug into it, it seemed way more complex than what I can understand in any reasonable time.

I am just trying to find a way how to detect changes of transforms of actors placed in a level and material assets during editor time (not runtime). Is this possible?

Thank you in advance.

I think AActor::OnConstruction is called when an actor is moved (if not disabled by user).

Yes, that’s true (Well actually OnConstruction is called by PostEditMove in that case) but that’s not the issue. I have a C++ class, where I can control what gets called when, and in this C++ class of mine, there’s UPROPERTY which picks other Actor in a level:


And I would like to detect when this **other **actor is moved in editor by the user, and based on that, call something on **my **class, not that other actor :slight_smile:

I think I would just store it’s current location and when I have to check I compare otherActor’s stored location to current location.
I don’t think there’s a builtin event in editor for that, never seen it anywhere.

Ha! Apparently there is. Thanks to my friend @ENiKS for figuring that out:



GEngine->OnActorMoved().AddUObject(this, &AYourClass::YourFunction);


GEngine broadcasts various changes, such as on ActorMoved, which you can bind to a function in your own class to get the notifications. The function must meet the criteria, in this case take AActor* as an argument.



void AYourClass::YourFunction(AActor* Actor)
{
    UE_LOG(LogTemp, Warning, TEXT("Level actor moved"));
}


After that, one can use the supplied AActor to match it to a specific actor and do stuff based on that :slight_smile:

I will add that to my notes, I didn’t know that was in there :stuck_out_tongue:

Here’s one more, for you and anyone else who will ever come across this. Apparently, generally most of the “On” functions have delegate binding, so for example if you have reference for a Material asset, and want to do something every time it recompiles, it works as follows:



UMaterial->OnMaterialCompilationFinished().AddUObject(this, &AYourClass::YourFunction);


Then it works, except in this case, the function needs to take UMaterialInterface*.