UE5 Custom Asset Add Reimport Button To Right-Click Menu

This tutorial covers extending your unreal engine custom asset right-click menu and adding the reimport button to that menu. It is a continuation of the How to add reimport functionality to a custom asset in unreal engine tutorial. We assume you have read that tutorial or you have a custom asset with reimport functions and would like to move the reimport button from the asset editor window to its right-click menu. Remember,  if at any point of our tutorials you get the unresolved external symbol error, which is either LNK2001 or LNK2019 error, You can follow the LNK2001  Solution tutorial. 

Inherit from FAssetTypeActions_Base

In order to extend custom asset right-click menu we are going to make use of the class FAssetTypeActions_Base.

This class inherits from IAssetTypeActions . They both have virtual functions we need to override to get this functionality but FAssetTypeActions_Base has some predefined logic built in.

				
					//FBcgAssetActions.h

class FBcgAssetActions : public FAssetTypeActions_Base
{
    virtual bool HasActions(const TArray<UObject*>& InObjects) const override { return true; }
    
    virtual void GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& MenuBuilder) override;
	
};
				
			

Override HasActions() Virtual Function

We override the HasActions() function to let the editor know that this custom asset has actions. To do that just return “true”; Actions are functions that can be called on the asset to do something. Most of the time this something is done on the custom asset or to the custom asset. It’s a fancy word for functions to run on button click.

Override GetActions() Virtual Function

GetActions() is our right-click menu populating function.
We will insert the Reimport button into the menu here.  MenuBuilder is passed in and we call addMenuEntry to add an entry.

				
					void FBcgAssetActions::GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& MenuBuilder)
{
	FText ButtonLabel=FText::FromString("Reimport/Replace");
	FText ButtonToolTip=FText::FromString("Replaces this BcgAsset with a source on disk");

	auto BcgAssets = GetTypedWeakObjectPtrs<UMidiAsset>(InObjects);

	//The function to call on click. Our CallBackFunction. It will pass the selected BcgAsets on to our callback function. 
	auto TDelegateExecuteAction=FExecuteAction::CreateSP(this,&FBcgAssetActions::ReimportBcgAsset, BcgAssets);

	auto UIAction=FUIAction(TDelegateExecuteAction);

	MenuBuilder.AddMenuEntry(ButtonLabel,ButtonToolTip,FSlateIcon(), UIAction);
}
				
			

Implementation of this function can get complicated because it requires some understanding of Templates, Shared Pointers and Delegates. We would rather cover this in our Plugin Development Course For Unreal Engine through video.

 

But to summarise we need to supply AddMenuEntry() function with some arguments.

The first is the label of the entry to add. 

The second is the tooltip the user will see when they hover.

For the 3rd, the SlateIcon, just call the default constructor.

The 4th Argument, the FUIAction is the tricky part.

We’ll cover the steps needed to create a FUIAction object that is needed by AddMenuEntry function.

  1. FUIAction is created by passing in an object of  FExecuteAction.

  2. To Create an object of FExecuteAction, we call the static function FExecuteAction::CreateSP()

  3. The FExecuteAction::CreateSP() function, is where we specify our callback function. I.e We specify the function to call when a button is clicked.

  4. The last argument in the CreateSP function is the payload, in our case the BcgAssets we want to pass on the callback function.

  5. Finally, create an object of FUIAction by passing in the object of FExecuteAction as the constructor argument;

FExecuteAction  is just a fancy delegate for Slate. When we create this delegate we immediately bind a function to it.

Your call-back function may need to receive payloads; We also specify these during the creation of the delegate.

We will cover the specifics of why to use CreateSP,  or how to use the other options in the course.

What you need to do in the callback function

When the user clicks your menu entry, this call back function will get called. In our case, we want to initiate the reimport functionality for all of our selected custom assets. This is how you do it:

				
					

void FBcgAssetActions::ReimportBcgAsset(TArray<TWeakObjectPtr<UBcgAsset>> BcgAssetsWeakPtrs)
{
	for (auto BcgAssetWeakPtr : BcgAssetsWeakPtrs)
	{
		UBcgAsset* BcgAsset= BcgAssetWeakPtr.Get();

		if(BcgAsset)
		{
			FReimportManager::Instance()->Reimport(BcgAsset,true);
		}
	}
}
				
			

You need to loop through all your objects and call Reimport() on the instance of FReimportManager.  Most of the code here is just us converting from weak pointers to raw pointers. The most important part is the Reimport function.

Register Your Asset Actions

You have now made it to the final part. You just need to go to your module implementation and register your Custom Asset Actions with AssetTools. You can do this when the module is starting up.

Conclusion

The Unreal Engine Plugin Development course covers more in-depth explanations for you to understand most datatypes and what unreal engine is doing under the hood but you can still get by, with these tutorials.