Extending asset type actions

Extending various engine asset types is relatively straightforward and seems like an obvious starting point for many plugins. However, from what I can see, inheriting and extending associated asset type actions isn’t possible since they are all hidden away in private engine code and not exported. If we register a custom asset type actions object, then this overrides those registered for the engine asset class and so the in-built actions are no longer available.

Is there a reason why asset type actions have not been exported? Am I missing something that would allow me to extend them?

Heya kamrann! The proper api exposure for these classes has not yet been determined, but one thing you can do is:

In the GetActions function of your custom subclass of IAssetTypeActions (lets call it FFooActions for asset type UFooAsset), you can get the IAssetTypeActions of the engine-level asset that UFooAsset extends by using IAssetTools::GetAssetTypeActionsForClass() and passing in the parent class of UFooAsset.
Just call GetActions on the engine-level IAssetTypeActions before or after adding your own (which will determine menu order).

It would look like this:
void FFooActions::GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& MenuBuilder)
{
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT(“AssetTools”));
TSharedPtr<IAssetTypeActions> EngineActions = AssetToolsModule.Get().GetAssetTypeActionsForClass(GetSupportedClass()->GetSuperClass()).Pin();
if (EngineActions.IsValid())
{
EngineActions->GetActions(InObjects, MenuBuilder);
}

// Add more actions here

}

I’d missed that function in the module interface. Awesome, thanks Bob!

I’m trying to do something similar, but in my case I’m trying to add a custom action for USkeletalMesh. Doing it the way BobTellez suggested would require my tiny little IAssetActions-derived class to implement all the functions that FAssetTypeActions_SkeletalMesh overrides, finding the correct FAssetTypeActions_SkeletalMesh instance inside them and calling its implementation. This would be extremely brittle.

Is there a better way for me to simply add a single menu item that runs a tool on the selected USkeletalMesh asset in the content browser?

Also, isn’t there the possibility that GetAssetTypeActionsForClass() returns the same object you’re currently executing in? Resulting in an infinite loop?

If you aren’t wanting to create a whole new asset, you could just extend the content browser right-click menu using the menu extenders in FContentBrowserModule::GetAllAssetViewContextMenuExtenders().
You would just filter whether you apply your extension based on whether any of the selected items were of the type you want to handle.

2 Likes