I have an editor component that I’m attaching to all kinds of actors to add some functionality to them. I need to know if the actor in question has been changed. Right now I’m using OnLevelMoved() but that doesn’t catch property sheet or material changes. It also fails to catch undo move events.
Is there a way to somehow catch another actor or component’s PostEditChange event inside my component? Can I subscribe to or listen for it somehow using a delegate? Delegates themselves confuse me a lot, so I’m unable to decide for myself if this is something I should be trying.
Delegates are awesome. I use them for almost all Event-Based stuff. You will learn to love them once 10 pieces of code and 7 Blueprints need to know when “ClientGameStarted” has been called
I have no clue concerning your original question though.
“Actor” being the other object I’d like to listen for the property change event from. Unfortunately that throws an error:
error C2228: left of '.BindUObject' must have class/struct/union
The documentation for this is weak if you’re like me and don’t quite understand what you’re doing. I’ve also tried variations of AddDynamic() and BindRaw(), they all have the same problem.
If all these actor blueprints are of the same Actor class, (or if you need, create their actor class, and reparent blueprints), you could handle it in Actors’ ‘PostEditChangeProperty()’. Check if there is a component that needs to be aware of the change, and call its ‘EditorUpdateProperty()’…
These only fire when editor changes properties – they’re excluded from packaged game.
If you don’t need to be notified of all changes, you can filter it down via something like:
If this also needs to trigger on spawning of actors (either via level load or via SpawnActor()), you should either add it to Actors’ BeginPlay() or OnConstruction(). Note that BeginPlay() fires after OnConstruction() and possibly after some Tick()'s if actor is spawned from server and replicated.
Finally, if Actor may or may not have this component (eg it is added by blueprint, and not in its C++) you can interpolate components via something like this:
for (auto Child : RootComponent->GetAttachChildren())
{
UOctaneSceneManager* OctaneSceneManagerComponent = Cast<UOctaneSceneManager>(Child);
if (OctaneSceneManagerComponent)
{
// do stuff
}
}
This is taking place in an editor plugin that adds a component to any actor the user may have chosen to use in their level so actually putting code into what is potentially a custom actor class is not possible as far as I’m aware.
The code example I put in above is being called on actor spawn via an OnLevelActorAdded() event, so new actors will always have their event bound to my listener. It’s at this point that my custom component is attached to the actor as well.
What would happen if I cast a random user class that inherits from AActor to a class I made that also inherits from AActor but has event handling code in it? Would that work? I’m guessing not.
I suppose my question comes down to “is there a way to bind a listener to any object’s event?” It seems like the convention is to start bindable events with “On” and there’s no “OnPostEditChangeProperty()” member, just the PostEditChangeProperty() that can be called rather than bound to.
I believe I’ve figured it out as close as I’m going to get it, but I’ve also run into a wall.
So in the engine PostEditChangeProperty() broadcasts an event to OnObjectPropertyChanged. So I set this up:
AActor * Actor = GetOwner();
DelegateHandles.Add(
FCoreUObjectDelegates::OnObjectPropertyChanged.AddRaw(Actor, &UOctaneComponent::OtherComponentPropertyChanged)
);
This kicks back an error that the second argument must be an AActor::* expression, not a UOctaneComponent::* expression.
So I tried moving the expression into a class that inherits from AActor, but I get the same error.
Basically it seems to suggest that AActor can add delegate listeners for AActor events but UOctaneComponent can never add delegate listeners for AActor events.
This is a huge problem. There are many situations where a plugin developer cannot modify a user’s custom class to add the code this needs, but still need to be able to track events for custom user objects. Likewise it’s unrealistic to expect a user to download a custom build of the engine just to add some custom code to AActor.