【UE4】編輯器開發(一)關卡編輯器拓展

一、菜單欄或工具欄中創建拓展項

在StartModule中創建拓展項:

//加載LevelEditor模塊,LevelEditor模塊負責的就是打開UE4編輯器首先映入眼簾的各個編輯窗口。其中包括菜單欄、工具欄、視窗、詳情面板、Modes面板、世界大綱面板等GUI功能。
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
{	//創建菜單欄項
	//創建拓展
	FTSharedPtr<FExtender> Extender = MakeShareable(new FExtender());
	/**
	@Param FName ExtensionHook. 項所在位置
	@Param EExtensionHook::Position HookPosition. 更具體的表示在ExtensionHook的相對位置:Before、After、First
	@Param const TSharedPtr< FUICommandList >& CommandList. 觸發命令
	@Param const FMenuBarExtensionDelegate& MenuBarExtensionDelegate. 單播委託。綁定一個方法,方法是關於返回拓展項的信息。
	*/
	MenuExtender->AddMenuBarExtension("Help", EExtensionHook::After, PluginCommands, FMenuBarEtensionDelegate::CreateRaw(this, &FStandaloneWinModule::AddMenuBarExtension));
	//添加拓展項到關卡編輯器
	LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
}
{	//創建菜單拓展項,就是菜單欄內的子項
	FTSharedPtr<FExtender> Extender = MakeShareable(new FExtender());
	MenuExtender->AddMenuExtension("WindowLayout", EExtensionHook::After, PluginCommands, FMenuExtensionDelegate::CreateRaw(this, &FStandaloneWinModule::AddMenuExtension));
	LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
}
{	//創建工具欄拓展項
	FTSharedPtr<FExtender> Extender = MakeShareable(new FExtender());
	MenuExtender->AddMenuExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FStandaloneWinModule::AddToolBarExtension));
	LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
}

拓展想項委託方法:

//此方法是創建一個菜單欄拓展項的委託方法,其它兩個方法與此類似。
void AddMenuBarExtension(FMenuBarBuilder& Builder)
{
	//AddMenuEntry有多個重載方法。可以通過其設置顯示文本、提示文本、圖標等參數。
	Builder.AddMenuEntry(FStandaloneWinCommands::Get().OpenPluginWindow);
}

void AddMenuExtension(FMenuBuilder& Builder)
{
	Builder.AddMenuEntry(FStandaloneWinCommands::Get().OpenPluginWindow);
}

void AddToolbarExtension(FToolBarBuilder& Builder)
{
	Builder.AddToolBarButton(FStandaloneWinCommands::Get().OpenPluginWindow);
}

菜單欄拓展項:
創建菜單欄拓展項
創建的菜單拓展項:
菜單子項
工具欄拓展項:
工具欄子項
上面構建菜單欄、菜單和工具欄拓展項的顯示參數分別使用FMenuBarBuilder、FMenuBuilder和FToolBarBuilder。他們的繼承關係爲:

FMultiBoxBuilder
FBaseMenuBuilder
FMenuBarBuilder
FMenuBuilder
FToolBarBuilder

二、菜單欄拓展項(Menu Bar Exntender)

創建下拉菜單

我們剛剛通過AddMenuEntry創建的是一個按鈕項,下面我們創建一個下拉菜單:

void AddMenuBarExtension(FMenuBarBuilder& Builder)
{
	/**
		@Param const FText& InMenuLabel. 第一個參數是菜單欄拓展項的顯示名稱。
		@Param const FText& InToolTip.	第二參數是菜單欄拓展項的提示名稱。
		@Param const FNewMenuDelegate& InPullDownMenu.	第三個是下拉菜單顯示的委託綁定,我們這裏綁定了剛剛的菜單拓展項委託方法。
		@Param FName InExtensionHook.	第四個參數是菜單欄拓展項的Hook名稱。
	*/
	Builder.AddPullDownMenu(
		LOCTEXT("PullMenu", "PullMenu"),
		LOCTEXT("This_Is_Pull_Menu", "This is Pull Menu"),
		FNewMenuDelegate::CreateRaw(this, &FStandaloneWinModule::AddMenuExtension),
		"AfterHelp"
	);
}

菜單欄拓展項:
菜單欄拓展項
菜單欄拓展項,菜單項我們綁定了下面的菜單委託方法,所以會顯示一個分割欄和兩個菜單項:
菜單欄拓展項

三、菜單拓展項(Menu Extender)

1. 創建分隔欄


void AddMenuExtension(FMenuBuilder& Builder)
{
	//第一個參數是分隔欄的Hook名,第二參數是分隔欄的顯示名稱
	Builder.BeginSection("CustomSection", LOCTEXT("CustomArea", "CustomArea"));
	//AddMenuEntry執行兩遍,將在分隔欄添加兩次拓展項
	Builder.AddMenuEntry(FStandaloneWinCommands::Get().OpenPluginWindow);
	Builder.AddMenuEntry(FStandaloneWinCommands::Get().OpenPluginWindow);
	Bilder.EndSection();
}

這個是最上面綁定的此方法,所以在Window菜單顯示:
下拉菜單分隔欄
這個是上面創建的菜單拓展項綁定此委託方法後,顯示的菜單項:
菜單欄拓展項

2. 創建分割線

void AddMenuExtension(FMenuBuilder& Builder)
{
	//第一個參數是分隔欄的Hook名,第二參數是分隔欄的顯示名稱
	Builder.BeginSection("CustomSection", LOCTEXT("CustomArea", "CustomArea"));
	//AddMenuEntry執行兩遍,將在分隔欄添加兩次拓展項
	Builder.AddMenuEntry(FStandaloneWinCommands::Get().OpenPluginWindow);
	//創建簡單的分割線
	Builder.AddMenuSeparator("SeparatorHook");
	Builder.AddMenuEntry(FStandaloneWinCommands::Get().OpenPluginWindow);
	Bilder.EndSection();
}

帶Hook的分割線:
帶Hook的分割線

3. 創建子下拉菜單

菜單欄下拉菜單內還可以創建子下拉菜單

void FStandaloneWinModule::AddMenuExtension(FMenuBuilder& Builder)
{
	Builder.BeginSection("CustomSection", LOCTEXT("CustomArea", "CustomArea"));

	Builder.AddMenuEntry(FStandaloneWinCommands::Get().OpenPluginWindow);
	Builder.AddMenuEntry(FStandaloneWinCommands::Get().OpenPluginWindow);
	Builder.AddMenuSeparator("SubMenuSp");
	/**
	創建子下拉菜單,與創建下拉菜單相似,該方法有多個重載方法
	@Param 子下拉菜單的父拓展項的顯示名稱
	@Param 提示名稱
	@Param 子下拉菜單項的委託
	@Param true-點擊顯示下拉菜單,false-鼠標移上去即顯示下拉菜單
	@Param 顯示圖標,這裏沒有設置
	@Param 當一個子項被選擇後,是否關閉子下拉菜單
	@Param Hook名稱
	*/
	Builder.AddSubMenu(
		LOCTEXT("SubMenu", "SubMenu"),
		LOCTEXT("This_is_Sub_Menu", "This is Sub Menu!"),
		FNewMenuDelegate::CreateRaw(this, &FStandaloneWinModule::AddSubMenuExtension),
		false,
		FSlateIcon(),
		true,
		"SubMenuHook"
	);
	Builder.EndSection();
}

void FStandaloneWinModule::AddSubMenuExtension(FMenuBuilder& Builder)
{
	Builder.AddMenuEntry(FStandaloneWinCommands::Get().OpenPluginWindow);
}

子下拉菜單:
子下拉菜單

4. 添加其它拓展項

自定義UI

/**
FMenuBuilder方法,添加自定義Slate控件
@param	InWidget			要顯示在下拉菜單的UI控件
@param	InLabel				控件前面顯示的標籤文本
@param	bNoIndent			如果爲true,移除UI控件左邊的邊距,默認爲false
@param	bSearchable			如果爲true,則Widget組件可被搜索到,默認爲true
*/
void AddWidget( TSharedRef<SWidget> InWidget, const FText& Label, bool bNoIndent = false, bool bSearchable = true );

輸入框

/**
添加一個可編輯文本框(輸入框)
@param	InLabel				顯示文本
@param	InToolTip			提示文本
@param	InIcon				顯示圖標
@param	InTextAttribute		編輯的文本內容
@param	InOnTextCommitted	文本提交觸發委託
@param	InOnTextChanged		文本修改觸發委託
@param	bInReadOnly			文本是否只允許可讀,默認爲false,表示文本框可編輯
*/
void AddEditableText( const FText& InLabel, const FText& InToolTip, const FSlateIcon& InIcon, const TAttribute< FText >& InTextAttribute, const FOnTextCommitted& InOnTextCommitted = FOnTextCommitted(), const FOnTextChanged& InOnTextChanged = FOnTextChanged(), bool bInReadOnly = false );

四、工具欄拓展項

1. 添加分隔欄和分割線

//添加分隔欄,參數爲Hook名稱
ToolBarBuilder.BeginSection("CustomHook");
ToolBarBuilder.AddToolBarButton(FStandaloneWinCommands::Get().OpenPluginWindow);
//添加分割線,參數爲Hook名稱
ToolBarBuilder.AddSeparator("ToolBarSep");
ToolBarBuilder.AddToolBarButton(FStandaloneWinCommands::Get().OpenPluginWindow);
ToolBarBuilder.EndSection();

分隔欄和分割線效果:
分隔欄和分割線

2. 創建下拉菜單

/**
 * 創建下拉菜單按鈕,其實這個方法不止可以創建下拉菜單,主要是可以創建一個帶有下拉圖標的按鈕
 *
 * @param	InAction				FUIAction類型,可以先通過其設置拓展項參數然後傳給此方法調用,也可以直接設置下面的參數
 * @param	InMenuContentGenerator	當拓展項被觸發,將會調用此委託,生成一個菜單
 * @param	InLabelOverride			標籤顯示名稱,參數如果省略,將會使用Action中的參數
 * @param	InToolTipOverride		按鈕提示名稱,參數如果省略,將會使用Action中的參數
 * @param	InIconOverride			按鈕圖標,參數如果省略,將會使用Action中的參數
 * @param	bInSimpleComboBox		如果爲true,標籤和圖標將不會被顯示,默認爲false
 * @param	InTutorialHighlightName	這個組件的標識名稱,在教程說明中將會高亮顯示,這個參數一般不用
 */

ToolBarBuilder.AddComboButton(
	FUIAction(),		//拓展項的設置我們使用下面的參數去設置
	FOnGetContent::CreateRaw(this, &FStandaloneWinModule::ToolBarCombox),	//綁定下面的UI委託方法
	LOCTEXT("ComboBox", "ComboBox"),					//標籤內容
	LOCTEXT("This_Is_ComboBox", "This is Combo Box!"),	//提示信息
	FSlateIcon(),			//不使用圖標
	false, 	//true-不顯示圖標和標籤,false-顯示圖標和標籤
);

//一個帶顯示文本框和輸入文本框的UI,將其綁定到工具欄的菜單內容生成委託上
TSharedRef<SWidget> FStandaloneWinModule::ToolBarCombox()
{
	TSharedPtr<SWidget> Combox = SNew(SBox).WidthOverride(150.f).HeightOverride(200.f)
		[
			SNew(SVerticalBox)+SVerticalBox::Slot().HAlign(HAlign_Fill).VAlign(VAlign_Top).AutoHeight()
			[
				SNew(STextBlock).Text(LOCTEXT("ThisComboBox", "This is Combo Box!"))
			]+SVerticalBox::Slot().HAlign(HAlign_Fill).VAlign(VAlign_Top).AutoHeight()
			[
				SNew(SEditableTextBox)
			]
		];
	return Combox.ToSharedRef();
}

工具欄下拉菜單是否顯示標籤和圖標的對比(第六個參數):
工具欄下拉菜單對比
創建的工具欄菜單效果:
工具欄菜單

五、 Viewport選中Actor的菜單拓展

//獲取Level Editor模塊
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
//獲取Viewport菜單上下文拓展項(Viewport中選中物體的右擊菜單拓展項),是一個委託數組
auto& LVCMExtenders = LevelEditorModule.GetAllLevelViewportContextMenuExtenders();
//在數組中添加一個新的拓展項,當右擊選中Actor並彈出菜單時,將會遍歷此數組並執行綁定的委託方法
LVCMExtenders.Add(FLevelEditorModule::FLevelViewportMenuExtender_SelectedActors::CreateRaw(this, &FStandaloneWinModule::LVCMExtender));
//委託方法,第一個參數是命令列表,第二個是選中的Actor數組,返回菜單拓展項(即顯示內容)
TSharedRef<FExtender> FStandaloneWinModule::LVCMExtender(const TSharedRef<FUICommandList> CommandList, const TArray<AActor*> Actors)
{
	//加載LevelEditor模塊
	FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
	//創建一個拓展項,與上一章中用法相似,用其拓展菜單項
	TSharedPtr<FExtender> Extender = MakeShareable(new FExtender());
	//設置菜單拓展項顯示內容,綁定的委託是上章創建的委託方法
	Extender->AddMenuExtension("ActorAsset", EExtensionHook::After, CommandList, FMenuExtensionDelegate::CreateRaw(this, &FStandaloneWinModule::AddMenuExtension));
	//auto& LVCMExtenders = LevelEditorModule.GetAllLevelViewportContextMenuExtenders();
	//LVCMExtenders.Pop();			//如果將最後一個(我們剛剛創建的)Extender移除,則將會在第一顯示菜單後,下次不會再顯示此項
	//返回拓展項,將會被顯示在菜單欄
	return Extender.ToSharedRef();
}

Viewport中選中物體的菜單效果:
場景中顯示菜單
World Outline中選中Actor的菜單效果:
世界大綱中選中Actor的菜單效果

六、其它常用可拓展編輯器模塊

類型 菜單欄拓展 工具欄拓展
AnimationBlueprintEditor
AnimationEditor
BehaviorTreeEditor
Cascade
CurveAssetEditor ×
CurveTableEditor ×
DataTableEditor ×
DestructibleMeshEditor
EnvironmentQueryEditor
FontEditor
Kismet ×
LevelEditor
MaterialEditor
Matinee
NiagaraEditor
Persona ×
PhysicsAssetEditor
SkeletalMeshEditor
StaticMeshEditor
StringTableEditor ×
TextureEditor
TranslationEditor ×
UMGEditor

加載模塊時,注意有些模塊的註冊名和類名不一致,比如Kistmet和FBlueprintEditorModule等。還要注意某些模塊的加載順序和時間。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章