ED08.FAssetEditorToolkit|自定义资源编辑器
大约 7 分钟
省流
FAssetEditorToolkit
一个封装了“UE 编辑器中资产编辑器所需基础功能(如菜单、工具栏、面板注册、布局、命令系统)的一套可扩展基类框架”。

virtual EAssetCommandResult OpenAssets(const FAssetOpenArgs& OpenArgs) const override;
EAssetCommandResult UAssetDefinitionDefault::OpenAssets(const FAssetOpenArgs& OpenArgs) const
{
if (GetAssetOpenSupport(FAssetOpenSupportArgs(OpenArgs.OpenMethod)).IsSupported)
{
FSimpleAssetEditor::CreateEditor(EToolkitMode::Standalone, OpenArgs.ToolkitHost, OpenArgs.LoadObjects<UObject>());
return EAssetCommandResult::Handled;
}
return EAssetCommandResult::Unhandled;
}
FAssetEditorToolkit | 派生类
1. FAssetEditorToolkit
(基础类)
- 是所有资源编辑器的基础类,但本身不带复杂业务逻辑
class FAssetEditorToolkit : public FBaseToolkit, public IAssetEditor
2. FWorkflowCentricApplication
(工作流驱动型编辑器)
面向复杂的、多面板、多模式切换的编辑器(如蓝图编辑器)
class FWorkflowCentricApplication : public FAssetEditorToolkit
- 内置
FApplicationMode
机制,可动态定义工作流
3. FSimpleAssetEditorToolkit
(轻量级编辑器)
class FSimpleAssetEditorToolkit : public FAssetEditorToolkit
- 无复杂的 ApplicationMode 和 Tab 分布结构
- 用于结构简单的编辑器,如只包含一个 Details 面板或 Preview 视图
- 通常通过创建一个简单布局,快速搭建 UI
FAssetEditorToolkit | 编辑器面板

区域 | 名称 | 构建方式 |
---|---|---|
顶部菜单栏 | Menu Bar | FMenuBarBuilder |
工具栏 | Tool Bar | FToolBarBuilder |
主要区域 | 中心面板 | FTabManager + DockTab |
底部栏 | Status Bar | SStatusBar + FStatusBarItem |
开干
1. build.cs引入模块
PublicDependencyModuleNames.AddRange( new string[] {"UnrealEd",});
2. 创建 FAssetEditorToolkit
//抽象
class ISuperComboGraphBlueprintEditor :
public FWorkflowCentricApplication{};
//具体派生实现类
class FSuperComboGraphAssetsEditor :
public ISuperComboGraphBlueprintEditor, public FGCObject,
public FNotifyHook, public FEditorUndoClient{ };
3. 基础接口
//唯一名称(内部识别名)。
virtual FName GetToolkitFName() const override
{
return FName("名字");
}; // Must implement in derived class!
//显示名称(用于标签栏 / 窗口标题等 UI 中)。
virtual FText GetBaseToolkitName() const override
{
return FName("标题名称");
}; // Must implement in derived class!
// World-Centric 模式(嵌入主编辑器窗口中)打开时,Tab 标签的前缀。
virtual FString GetWorldCentricTabPrefix() const override
{
return LOCTEXT("WorldCentricTabPrefix", "Super ComboGraph ").ToString();
}; // Must implement in derived class!
World-Centric 模式
模式 | 外观描述 |
---|---|
World-Centric | 编辑器嵌入在主编辑器窗口,作为一个 Tab 显示 |
Standalone | 编辑器作为一个新的独立窗口单独弹出 |
4. 定义|TabId
.h
static const FName PropertiesTabId;
.cpp
const FName FSuperComboGraphAssetsEditor::PropertiesTabId(TEXT("属性_Properties"));
5. 创建|CreateXXXWidget
.h
void CreateInternalWidgets();
.cpp
void FSuperComboGraphAssetsEditor::CreateInternalWidgets()
{
FDetailsViewArgs Args;
Args.bHideSelectionTip = true;
Args.NotifyHook = this;
FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
SuperComboGraphProperties = PropertyModule.CreateDetailView(Args);
SuperComboGraphProperties->SetObject(SuperComboGraph);
}
6. 注册| RegisterTabSpawners
.h
virtual void RegisterTabSpawners(const TSharedRef<class FTabManager>& TabManager) override;
virtual void UnregisterTabSpawners(const TSharedRef<class FTabManager>& TabManager) override;
.cpp
void FSuperComboGraphAssetsEditor::RegisterTabSpawners(const TSharedRef<FTabManager>& Manager)
{
/*注册工作区的菜单分类*/
WorkspaceMenuCategory = Manager->AddLocalWorkspaceMenuCategory(LOCTEXT("WorkspaceMenu_SuperComboGraph", "Super ComboGraph "));
const auto WorkspaceMenuCategoryRef = WorkspaceMenuCategory.ToSharedRef();
/*注册自定义的标签页(Tab)*/
FAssetEditorToolkit:: RegisterTabSpawners(Manager);
/*Details / 属性面板*/
Manager->RegisterTabSpawner( PropertiesTabId, FOnSpawnTab::CreateSP(this, &FSuperComboGraphAssetsEditor::SpawnTab_Properties) )
.SetDisplayName( LOCTEXT("DetailsTab", "Details") )
.SetGroup(WorkspaceMenuCategoryRef)
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Details"));
}
void FSuperComboGraphAssetsEditor::UnregisterTabSpawners(const TSharedRef<FTabManager>& Manager)
{
Manager->UnregisterTabSpawner( PropertiesTabId);
}
7. 构建| SpawnTab_XXX


.h
/** Properties tab 属性标签 */
TSharedPtr<class IDetailsView> SuperComboGraphProperties;
.cpp
TSharedRef<SDockTab> FSuperComboGraphAssetsEditor::SpawnTab_Properties(const FSpawnTabArgs& Args) const
{
check(Args.GetTabId() == PropertiesTabId);
return SNew(SDockTab).Label(LOCTEXT("SuperComboGraphDetailsTitle", "Details"))
[
SuperComboGraphProperties.ToSharedRef()
];
}
8.插入|Layout布局
.h
/** 创建布局 */
TSharedRef<FTabManager::FLayout> CreateEditorLayout();
.cpp
TSharedRef<FTabManager::FLayout> FSuperComboGraphAssetsEditor::CreateEditorLayout()
{
return FTabManager::NewLayout("Standalone_SuperComboGraphEditor_Layout_v5")
->AddArea
(
FTabManager::NewPrimaryArea()
->SetOrientation(Orient_Vertical)
->Split(
FTabManager::NewSplitter()
->SetOrientation(Orient_Horizontal)
->Split(
FTabManager::NewStack()
->SetSizeCoefficient(0.6)
->SetHideTabWell(true)
->AddTab(PropertiesTabId, ETabState::OpenedTab)
)
)
);
}
9. 初始化
FAssetEditorToolkit::InitAssetEditor(
Mode,
InitToolkitHost,
TEXT("SuperComboGraphEditor"),
StandaloneDefaultLayout,
false,
true,
ObjectToEdit,
false
);

完整案例
.h
//抽象
ISuperComboGraphBlueprintEditor : public FWorkflowCentricApplication
class FSuperComboGraphAssetsEditor : public ISuperComboGraphBlueprintEditor
{
public :
FSuperComboGraphAssetsEditor(){};
virtual ~FSuperComboGraphAssetsEditor() override;
/** 初始化SuperComboGraphAssetsEditor */
void InitAssetsEditor(const EToolkitMode::Type Mode, const TSharedPtr<class IToolkitHost>& InitToolkitHost,UObject* ObjectToEdit);
/** IToolkit interface */
virtual FName GetToolkitFName() const override;
virtual FText GetBaseToolkitName() const override;
virtual FString GetWorldCentricTabPrefix() const override;
virtual void RegisterTabSpawners(const TSharedRef<class FTabManager>& TabManager) override;
virtual void UnregisterTabSpawners(const TSharedRef<class FTabManager>& TabManager) override;
private:
/** 创建控件 */
void CreateInternalWidgets();
/** 创建标签页 */
TSharedRef<SDockTab> SpawnTab_Properties(const FSpawnTabArgs& Args) const;
/** 创建布局 */
TSharedRef<FTabManager::FLayout> CreateEditorLayout();
private:
/** Properties tab 属性标签 */
TSharedPtr<class IDetailsView> SuperComboGraphProperties;
/** The tab ids for all the tabs used */
static const FName PropertiesTabId;
};
.cpp
const FName FSuperComboGraphAssetsEditor::PropertiesTabId( TEXT( "SuperComboGraphAssetsEditor_Properties" ) );
FName FSuperComboGraphAssetsEditor::GetToolkitFName() const
{
/*返回这个 Toolkit 的内部标识名,用于唯一标识当前编辑器的类型。*/
return FName("SuperComboGraphAssetsEditor");
}
FText FSuperComboGraphAssetsEditor::GetBaseToolkitName() const
{
/*显示在窗口左上角标签中。。*/
return LOCTEXT("AppLabel", "Super ComboGraph Editor");
}
FString FSuperComboGraphAssetsEditor::GetWorldCentricTabPrefix() const
{
/*在世界中心模式中,窗口的前缀名(嵌在主编辑器中的情况下)。*/
return LOCTEXT("WorldCentricTabPrefix", "Super ComboGraph ").ToString();
}
void FSuperComboGraphAssetsEditor::CreateInternalWidgets()
{
FDetailsViewArgs Args;
Args.bHideSelectionTip = true;
Args.NotifyHook = this;
FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked<FPropertyEditorModule>("PropertyEditor");
SuperComboGraphProperties = PropertyModule.CreateDetailView(Args);
SuperComboGraphProperties->SetObject( SuperComboGraph );
}
TSharedRef<SDockTab> FSuperComboGraphAssetsEditor::SpawnTab_Properties(const FSpawnTabArgs& Args) const
{
check( Args.GetTabId() == PropertiesTabId );
return SNew(SDockTab)
.Label(LOCTEXT("SuperComboGraphDetailsTitle", "Details"))
[
SuperComboGraphProperties.ToSharedRef()
];
}
void FSuperComboGraphAssetsEditor::RegisterTabSpawners(const TSharedRef<FTabManager>& Manager)
{
/*注册工作区的菜单分类*/
WorkspaceMenuCategory = Manager->AddLocalWorkspaceMenuCategory(LOCTEXT("WorkspaceMenu_SuperComboGraph", "Super ComboGraph "));
const auto WorkspaceMenuCategoryRef = WorkspaceMenuCategory.ToSharedRef();
/*注册自定义的标签页(Tab)*/
FAssetEditorToolkit:: RegisterTabSpawners(Manager);
/*Details / 属性面板*/
Manager->RegisterTabSpawner( PropertiesTabId, FOnSpawnTab::CreateSP(this, &FSuperComboGraphAssetsEditor::SpawnTab_Properties) )
.SetDisplayName( LOCTEXT("DetailsTab", "Details") )
.SetGroup(WorkspaceMenuCategoryRef)
.SetIcon(FSlateIcon(FAppStyle::GetAppStyleSetName(), "LevelEditor.Tabs.Details"));
}
void FSuperComboGraphAssetsEditor::UnregisterTabSpawners(const TSharedRef<FTabManager>& Manager)
{
Manager->UnregisterTabSpawner( PropertiesTabId);
}
void FSuperComboGraphAssetsEditor::InitAssetsEditor(const EToolkitMode::Type Mode,const TSharedPtr<IToolkitHost>& InitToolkitHost, USuperComboGraph* ObjectToEdit)
{
/*创建细节面板*/
CreateInternalWidgets();
/*初始化*/
InitAssetEditor(Mode,
InitToolkitHost,
TEXT("SuperComboGraphEditor"),
CreateEditorLayout(),
false,
true,
ObjectToEdit,
false);
}
TSharedRef<FTabManager::FLayout> FSuperComboGraphAssetsEditor::CreateEditorLayout()
{
return FTabManager::NewLayout("Standalone_SuperComboGraphEditor_Layout_v5")
->AddArea
(
FTabManager::NewPrimaryArea()
->SetOrientation(Orient_Vertical)
->Split(
FTabManager::NewSplitter()
->SetOrientation(Orient_Horizontal)
->Split(
FTabManager::NewStack()
->SetSizeCoefficient(0.6)
->SetHideTabWell(true)
->AddTab(PropertiesTabId, ETabState::OpenedTab)
)
)
);
}
#undef LOCTEXT_NAMESPACE