Adding custom gizmos to actor without editor extension?

Is there any way to add a gizmo to an actor placed in the level editor without extending the editor itself? For instance, I want to add some code to my wall pieces that shows some custom gizmos when they are selected. So for instance, I would select a wall piece, and some buttons would pop up, one would allow me to add another wall piece on the side it appears. Another would allow me to add a corner piece.

Now obviously this would be possible with an editor extension, but then I’m putting a nice coupling between my gameplay objects and the editor which I’m not super happy with.

Is there anything like this I can extend?

Did you ever find a solution to this?

This could be accomplished with a plugin that implemented a new asset type and possibly a level editor mode. Quite a bit of work, but wouldn’t be an engine modification.

I am also interested in doing this. Anyone find a good place to start?

I found the answer myself.

It isn’t very hard once you know what to do. I’m surprised this type of question goes unanswered.

ANSWER: Make a variable of type Vector or Transform on your actor and check [x] Editable and [x] Show 3D Widget - then you get an extra widget showing up for that vector variable.

Oddly enough rotators don’t have the same option.

In order to create a panel or button pop-up that has functionality within the editor you’d either have to extend the editor itself, or create a plugin.

As CleanCut suggests, you can add a variable that includes a widget in the viewport; but you can’t directly tie any special UI buttons or panel popups to it. It just gives you a handle to manipulate the variable value itself (i.e. with a vector you get a translation widget that updates the vector’s X,Y,Z values based on the handle’s location.

You might be able to do a bit of a workaround by using PostEditChangeProperty; you could create a vector and display a 3D widget:

UPROPERTY(EditAnywhere, BlueprintReadWrite, Meta = (MakeEditWidget = true))
FVector WallSpawn;

And then you can use the handle to modify the value, detect that change via PostEditChangeProperty, and trigger your spawn.

void AWallPiece::PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent)  
    //Get the name of the property that was changed  
    FName PropertyName = (PropertyChangedEvent.Property != nullptr) ? PropertyChangedEvent.Property->GetFName() : NAME_None;  

    //Check if it's the property we want  
    if ((PropertyName == GET_MEMBER_NAME_CHECKED(AWallPiece, WallSpawn)))  
        //trigger your desired action if it is


    // Call the base class version  

Basically you’re hacking the FVector value modification to behave as a button.

It’s quite a bit cludgy, though; and means your game object will be cluttered with unnecessary variables.

“Now obviously this would be possible with an editor extension, but then I’m putting a nice coupling between my gameplay objects and the editor which I’m not super happy with.”

You don’t have to modify your game object code at all. You can build the plugin/editor extension to just detect the presence of your target objects within the level (and could even check for multiple, different classes) and then build the widgets based on their location in the game world. They can be completely independent of the runtime elements.

You can build your plugin to respond to editor events and detect when objects of the type you like are selected, and then have the plugin trigger the visibility of the panels. But again, this isn’t tying your gameplay objects to the editor, it’s tying your plugin to the editor (but without the editor the plugin has no functionality or reason to exist).

Quite the contrary, building the functionality into your game actors more closely ties them to the editor, as with the PostEditChangeProperty method above. You can include #if WITH_EDITOR, but the code itself is still tied to Unreal’s editor.

This doesn’t actually answer the question, though. It creates a widget, but it doesn’t bring up a panel or a button; and doesn’t tie that widget to any spawning action or other method. It’s just a graphical way to modify the variable itself.