You can extend the menus displayed in asset editors such as blueprint editors or others via UToolMenus.
The main complication with this is getting the asset that’s being currently edited. The built-in menus access this via FAssetEditorToolkit as the asset editors inherit from it. In order to know which asset our button should act on, we need to get the toolkit.
We can do this from UAssetEditorToolkitMenuContext. Getting it is slightly complicated however, see the example below:
//This is the part of the asset editor menu which contains the buttons
//on the very left side of it
UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("AssetEditorToolbar.CommonActions");
//Add a section for our button
FToolMenuSection& Section = Menu->FindOrAddSection("MyNewSection");
//We need to use a dynamic entry in order to get access to the context
//at the time of when the button is actually being clicked
Section.AddDynamicEntry(NAME_None, FNewToolMenuSectionDelegate::CreateLambda([this](FToolMenuSection& Section)
{
//This gives us the active context for the asset this menu is for
UAssetEditorToolkitMenuContext* Context = Section.FindContext<UAssetEditorToolkitMenuContext>();
//Create a new toolbar button into the menu. The key point here
//is to use a FUIAction with a lambda, as that gives us easy access
//to the context and we can determine which asset is the active one
Section.AddEntry(FToolMenuEntry::InitToolBarButton(
NAME_None,
FUIAction(FExecuteAction::CreateLambda([Context]()
{
//Get the set of assets being edited
const TArray<UObject*>& Objects = Context->GetEditingObjects();
//Do something with Objects - The item at index 0
//is the asset where the button was clicked.
})),
TAttribute<FText>(),
TAttribute<FText>(),
//Buttons need some icon for them
FSlateIcon(FAppStyle::GetAppStyleSetName(), "Icons.World")
));
}));