Custom Asset types commonly have special functions you wish to be able to perform on them. For example, converting images to sprites is an option you wouldn't want to add to any other Asset type. You can create custom context menu entries for specific Asset types in order to make those functions accessible to users.
FAssetTypeActions_Base
. You'll need to include AssetTypeActions_Base.h
in the header file.virtual bool HasActions(const TArray<UObject*>& InObjects) const override; virtual void GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& MenuBuilder) override; virtual FText GetName() const override; virtual UClass* GetSupportedClass() const override; virtual FColor GetTypeColor() const override; virtual uint32 GetCategories() override;
void MyCustomAssetContext_Clicked();
.cpp
file:bool FMyCustomAssetActions::HasActions(const TArray<UObject*>& InObjects) const { return true; } void FMyCustomAssetActions::GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& MenuBuilder) { MenuBuilder.AddMenuEntry( FText::FromString("CustomAssetAction"), FText::FromString("Action from Cookbook Recipe"), FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.ViewOptions"), FUIAction( FExecuteAction::CreateRaw(this, &FMyCustomAssetActions::MyCustomAssetContext_Clicked), FCanExecuteAction())); } uint32 FMyCustomAssetActions::GetCategories() { return EAssetTypeCategories::Misc; } FText FMyCustomAssetActions::GetName() const { return FText::FromString(TEXT("My Custom Asset")); } UClass* FMyCustomAssetActions::GetSupportedClass() const { return UMyCustomAsset::StaticClass(); } FColor FMyCustomAssetActions::GetTypeColor() const { return FColor::Emerald; } voidFMyCustomAssetActions::MyCustomAssetContext_Clicked() { TSharedRef<SWindow> CookbookWindow = SNew(SWindow) .Title(FText::FromString(TEXT("Cookbook Window"))) .ClientSize(FVector2D(800, 400)) .SupportsMaximize(false) .SupportsMinimize(false); IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame")); if (MainFrameModule.GetParentWindow().IsValid()) { FSlateApplication::Get().AddWindowAsNativeChild(CookbookWindow, MainFrameModule.GetParentWindow().ToSharedRef()); } else { FSlateApplication::Get().AddWindow(CookbookWindow); } };
StartupModule()
function:IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get(); auto Actions =MakeShareable(new FMyCustomAssetActions); AssetTools.RegisterAssetTypeActions(Actions); CreatedAssetTypeActions.Add(Actions);
ShutdownModule()
function:IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get(); for (auto Action : CreatedAssetTypeActions) { AssetTools.UnregisterAssetTypeActions(Action.ToSharedRef()); }
FAssetTypeActions_Base
, so we need to inherit from that class.FAssetTypeActions_Base
is an abstract class that defines a number of virtual functions that allow for extending the context menu. The interface which contains the original information for these virtual functions can be found in IAssetTypeActions.h
.IAssetTypeActions::HasActions ( const TArray<UObject*>& InObjects )
is the function called by the engine code to see if our AssetTypeActions
class contains any actions that can be applied to the selected objects.IAssetTypeActions::GetActions(const TArray<UObject*>& InObjects, class FMenuBuilder& MenuBuilder)
is called if the HasActions
function returns true
. It calls functions on MenuBuilder
to create the menu options for the actions that we provide.IAssetTypeActions::GetName()
returns the name of this class.IAssetTypeActions::GetSupportedClass()
returns an instance of UClass
which our actions class supports.IAssetTypeActions::GetTypeColor()
returns the color associated with this class and actions.IAssetTypeActions::GetCategories()
returns a category appropriate for the asset. This is used to change the category under which the actions show in the context menu.HasActions
simply returns true
under all circumstances relying on filtering based on the results of GetSupportedClass
.GetActions
, we can call some functions on the MenuBuilder
object that we are given as a function parameter. The MenuBuilder
is passed as a reference, so any changes that are made by our function will persist after it returns.AddMenuEntry
has a number of parameters. The first parameter is the name of the action itself. This is the name that will be visible within the context menu. The name is an FText
so that it can be localized should you wish. For the sake of simplicity, we construct FText
from a string literal and don't concern ourselves with multiple language support.FText
, which we construct by calling FText::FromString
. This parameter is the text displayed on a tooltip if the user hovers over our command for more than a small amount of time.FSlateIcon
for the command, which is constructed from the LevelEditor.ViewOptions
icon within the editor style set.FUIAction
instance. The FUIAction
is a wrapper around a delegate binding, so we use FExecuteAction::CreateRaw
to bind the command to the MyCustomAsset_Clicked
function on this very instance of FMyCustomAssetActions
.MyCustomAssetContext_Clicked
function will be run.GetName
returns the name of our Asset type. This string will be used on the thumbnail for our Asset if we don't set one ourselves, apart from being used in the title of the menu section that our custom Assets will be placed in.GetSupportedClass
returns UMyCustomAsset::StaticClass()
, as this is the Asset type we want our actions to operate on.GetTypeColor()
returns the color that will be used for color coding in Content Browser—the color is used in the bar at the bottom of the asset thumbnail. I've used Emerald here, but any arbitrary color will work.MyCustomAssetContext_Clicked()
function.SWindow
.SWindow
is the Slate Window—a class from the Slate UI framework.SNew
function, which returns an instance of the widget requested.builder
design pattern, which means that all the functions that are chained after SNew
returns a reference to the object that was being operated on.SWindow
, then set the window title, its client size or area, and whether it can be maximized or minimized.IMainFrameModule
class. It's a module, so we use the Module Manager to load it.LoadModuleChecked
will assert if we can't load the module, so we don't need to check it.FSlateApplication::AddWindowAsNativeChild
to add our window as a child of the top-level parent window.AddWindow
to add the new window without parenting it to another window within the hierarchy.StartupModule
and ShutdownModule
functions.StartupModule
, we load the Asset Tools module using Module Manager.AssetModule.RegisterAssetTypeActions,
and pass in an instance of our actions class.Actions
instance so that we can unregister it later.ShutdownModule
, we again retrieve an instance of the Asset Tools module.Actions
instances that we populated earlier, and call UnregisterAssetTypeActions
, passing in our Actions
class so it can be unregistered.StaticClass
will match the one returned by GetSupportedClass
. The editor will then call GetActions
, and display the menu with the alterations made by our implementation of that function.CustomAssetAction
button is clicked, our custom MyCustomAssetContext_Clicked
function will be called via the delegate that we created.3.143.9.254