The basic class to develop asset editor is FAssetEditorToolkit, which contains basic functions for asset editor development. The structure is given below.
An asset editor consists of a number of tabs. The basic flow to create an asset editor:
Create a editor class, derived from FAssetEditorToolkit.
Create a layout for your editor.
Register and spawn tabs by FTabManager.
For your subclass of FAssetEditorToolkit, the key functions should be called or overrided are given below.
virtual void InitAssetEditor(const EToolkitMode::Type Mode, const TSharedPtr<IToolkitHost>& InitToolkitHost, const FName AppIdentifier, const TSharedRef<FTabManager::FLayout>& StandaloneDefaultLayout, const bool bCreateDefaultStandaloneMenu, const bool bCreateDefaultToolbar, UObject* ObjectToEdit, const bool bInIsToolbarFocusable = false, const bool bInUseSmallToolbarIcons = false);
virtual void RegisterTabSpawners(const TSharedRef<FTabManager>& TabManager) override;
InitAssetEditor should be called from your editor class, it can create default layout, menu and toolbar. AppIdentifier is an unique identification name.
RegisterTabSpawners should be overrided to add different tabs. For example:
void FSoundSubmixEditor::RegisterTabSpawners(const TSharedRef<FTabManager>& InTabManager)
{
WorkspaceMenuCategory = InTabManager->AddLocalWorkspaceMenuCategory(LOCTEXT("WorkspaceMenu_SoundSubmixEditor", "Sound Submix Editor"));
auto WorkspaceMenuCategoryRef = WorkspaceMenuCategory.ToSharedRef();
FAssetEditorToolkit::RegisterTabSpawners(InTabManager);
InTabManager->RegisterTabSpawner(GraphCanvasTabId, FOnSpawnTab::CreateSP(this, &FSoundSubmixEditor::SpawnTab_GraphCanvas))
.SetDisplayName(LOCTEXT("GraphCanvasTab", "Graph"))
.SetGroup(WorkspaceMenuCategoryRef)
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "GraphEditor.EventGraph_16x"));
InTabManager->RegisterTabSpawner(PropertiesTabId, FOnSpawnTab::CreateSP(this, &FSoundSubmixEditor::SpawnTab_Properties))
.SetDisplayName(LOCTEXT("PropertiesTab", "Details"))
.SetGroup(WorkspaceMenuCategoryRef)
.SetIcon(FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.Tabs.Details"));
}
For some assets that have different application mode (ex. BehaviorTree), UE4 provide a class derived from FAssetEditorToolkit to achieve this conveniently, called FWorkflowCentricApplication.
This FWorkflowCentricApplication editor can have several application mode, such as FBehaviorTreeEditorApplicationMode and FBlackboardEditorApplicationMode in behavior tree editor.
Every FApplicationMode has its layout and tabs.
Every FApplicationMode has a number of FWorkflowTabFactory.
Each FWorkflowTabFactory will create a tab for different purpose.
As the structure of FWorkflowCentricApplication is clearer, I recommend to create asset editor class, derived form it.
class FTestEditor : public FWorkflowCentricApplication, public FEditorUndoClient, public FNotifyHook
{
public:
virtual void RegisterTabSpawners(const TSharedRef<class FTabManager>& TabManager) override;
void InitEditor(const EToolkitMode::Type Mode, const TSharedPtr< class IToolkitHost >& InitToolkitHost, UObject* InObject);
...
}
As I mentioned in UE4 User-Defined Asset Type Action, the entry of asset editor is defined in the type action class.
void FAssetTypeActions_UserDefinedAsset::OpenAssetEditor(const TArray<UObject*>& InObjects, TSharedPtr<IToolkitHost> EditWithinLevelEditor)
{
EToolkitMode::Type Mode = EditWithinLevelEditor.IsValid() ? EToolkitMode::WorldCentric : EToolkitMode::Standalone;
for (auto Object : InObjects)
{
auto NewAsset = Cast<UUserDefinedAsset>(Object);
if (NewAsset != nullptr)
{
TSharedRef< FTestEditor > NewEditor(new FTestEditor());
NewEditor->InitEditor(Mode, EditWithinLevelEditor, NewAsset);
}
}
}