top of page

Editor Utility : Natural Selection

A descendant class from Editor Utility Widget doesn't appear to get the full range of blueprint nodes the straight-up Editor Utility Widget has, including 'Get Selected Actors', shown below, that I happen to need! I have an Editor Utility Widget class in the C++ source of my project, that itself has a blueprint-created instance added in the editor. I hoped to get selected actors in the scene to count them up and list them in the widget UI.

If I had just made a blueprint utility widget in the content browser, this node would show up, but apparently given my class extends from a C++ Editor Utility Widget, I'm missing the node.

So, in C++ there's some clever tricks to make essentially a workaround version of that node.

First, I added a bool bSelectionChanged that is used to track when the current editor selection changes.

The function ObtainSelectedLevelActors replaces the missing unreal node, and returns an array of actors currently selected. The Construct and Destruct parts handle the utility widget's setup and removal. NativeConstruct is called when the widget is created. It loads the Level Editor module and binds the OnSelectionChanged function to the OnActorSelectionChanged delegate. This means the OnSelectionChanged function will be triggered whenever an actor is selected or deselected in the editor.

NativeDestruct is called when the widget is destroyed. It unbinds the OnSelectionChanged function from the delegate, ensuring the widget stops listening for selection changes when it's no longer in use.

FunBPHelperUtility.h

FunBPHelperUtility.cpp

Note that bSelectionChanged is set true here, when the OnSelectionChanged function runs.

Back in unreal editor, the BP instance of this, checks on Tick if bSelectedChanged is true (it doesn't proceed unless it's true).

While the List Selection function polls the scene for all the selected actors, it only does it once in a while, as the selection isn't changed very frequently by the user. It could check less often, but most of the time it's false, and stops. List Selection only says what to do when the scene selection changes (either adding to it or removing from it). Mostly, it's sending numbers and asset names to the widget UI.

This link is to the blueprint pastebin of the image below for the function 'List Selection':

The highlighted node 'ObtainSelectedLevelActors' replaces the missing native unreal engine node 'GetSelectedLevelActors', and it gives an array of actors from which I filter the name and count how many of whatever class is first, so I can display this, as shown below:

The blue numbers count up, and the text 'DirectionalLight' changes depending on what actor was selected first.When nothing is selected, everything resets. It's a lot of jumping through hoops to do something fairly simple.


You may notice that the script checks if the actor's automatically generated Name contains UAID suffix and removes it if so. But not all actors include that! PlayerStarts do, but DirectionalLights don't. Shrug. Maybe there's other inconsistent actor naming I should watch for? Importantly, the List Selection function sets the bSelectionChanged bool to be false once the function is done. This stops further ticking until the scene selection actually changes again.

The other thing that caught me out was that if I clicked the same object a few times, it would select/deselect/select and increment the count to 3, so I decided to pass everything through a 'Counted' Set, which only allows unique actors to be added to it, and it's cleared each tick if the function is called. What's nice about all this is that it tracks the selection from both the Viewport and from the World Outliner.

Comments


Featured Posts
Recent Posts
Search By Tags
Follow Us
  • Facebook Basic Square
  • Twitter Basic Square
  • Google+ Basic Square
bottom of page