#if WITH_EDITORONLY_DATA
void AMyActor::OnObjectSelected(UObject* Object)
{
UE_LOG(LogTemp, Log, TEXT("%s::OnObjectSelected(): %s was %s."), *GetName(), *Object->GetName(), *FString(Object->IsSelected() ? "selected" : "de-selected"));
if (Object == this)
{
SelectedInEditor = true;
...do stuff when your actor is selected...
}
else if (SelectedInEditor && !IsSelected())
{
SelectedInEditor = false;
...do stuff when your actor is un-selected...
}
}
#endif
Beware: OnObjectSelected will be called on every actor you have in the scene. This is why you have to filter out only what is relevant to your object (hence the if (Object == this) ).
Itās a bit harder to detect that an object that is un-selected. You have to keep a flag (bool SelectedInEditor) on your actor that is set when it is selected. Then, when you receive the object selected event for another object and IsSelected() on yourself returns false, you are officially un-selected.
I came across this thread and while the above solution works great for selecting actors in the viewport, it does not work when selecting actors in the World Outliner (see Unreal Engine Issue (UE-46676)).
In case anyone comes by this thread and is wondering, like me, how to get this working with the World Outliner, I wanted to share a similar solution that works any time an actor is selected in the editor, whether itās through the viewport or World Outliner:
(This was tested in Unreal Engine 4.27)
In the Actorās constructor, bind the selection event like this:
#include "Engine/Selection.h"
AExampleActor::AExampleActor()
{
#if WITH_EDITOR
// Broadcast whenever the editor selection changes (viewport
// or world outliner)
USelection::SelectionChangedEvent.AddUObject(this,
&AExampleActor::OnSelectionChanged);
#endif
}
void AExampleActor::OnSelectionChanged(UObject* NewSelection)
{
TArray<AExampleActor*> SelectedExampleActors;
// Get ExampleActors from the selection
USelection* Selection = Cast<USelection>(NewSelection);
if (Selection != nullptr)
{
Selection->GetSelectedObjects<AExampleActor>(
SelectedExampleActors);
}
// Search the selection for this actor
for (AExampleActor* SelectedExampleActor : SelectedExampleActors)
{
// If our actor is in the selection and was not previously
// selected, then this selection change marks the actor
// being selected
if (SelectedExampleActor == this && !bSelectedInEditor)
{
// Respond to this actor being selected
bSelectedInEditor = true;
}
}
// If our record shows our actor is selected, but IsSelected() is false,
// this selection change marks the actor being deselected
if (bSelectedInEditor && !IsSelected())
{
// Respond to this actor being deselected
bSelectedInEditor = false;
}
}
#endif
I found this solution in Unreal Engineās AIModuleās EQSTestingPawn.cpp, which implements a lot of editor-only debugging tools like this if you want to see more examples / robust editor debugging tools.
This worked well for me even in the PIE world! I came here looking for answers after trying EditorActorSubsystem->GetSelectedLevelActors() only to realize this only works in the editor itself and not the running game in PIE. Above solution works in both!
I tried to use this but it kept giving me unresolved symbol error eventhogh include was there and engine is already in dependencies, i do not know what iām doing wrong or anyone else has that problem, but any help would be appreciated
in ue5ļ¼just test 5.0ļ¼ in Editor utility widget ļ¼ you can use get leveleditorsubsystem getselectionset event to on selection change bind customevent
I have been unable to get the C++ working at all, because I canāt get it to compile.
Creating library F:\GrimmTales\Repositories\TrainGame\Binaries\Win64\UnrealEditor-TrainGame.patch_2.lib and object F:\GrimmTales\Repositories\TrainGame\Binaries\Win64\UnrealEditor-TrainGame.patch_2.exp
SelectableActor.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: static class USelection::FOnSelectionChanged USelection::SelectObjectEvent" (__imp_?SelectObjectEvent@USelection@@2VFOnSelectionChanged@1@A) referenced in function "public: __cdecl ASelectableActor::ASelectableActor(void)" (??0ASelectableActor@@QEAA@XZ)
F:\GrimmTales\Repositories\TrainGame\Binaries\Win64\UnrealEditor-TrainGame.patch_2.exe : fatal error LNK1120: 1 unresolved externals
Iāve spent all day trying to figure out whatās wrong, and I just donāt get it. Iām coming from Unity so I understand the separation between runtime/editor code, and I have the include and editor func call wrapped in the editor compiler flags. But I just canāt get the thing to compile. I have no idea what Iām doing wrong. I canāt find any information about this
I had a similar issue and needed to update the PublicDependencyModuleNames in the Project.build.cs file where Project is your project name. For instance like this:
To complement Freedomistās answer, this now can be done entirely in BP. Just create an editor utility object that runs at editor startups then bind the said delegate:
Performance wise I wouldnāt recommend binding this on a per actor basis if you were in C++ as each actor would have to sift through the same list. That could potentially freeze the editor if there were too many actors all selected at once.