文章目录
一、菜单栏或工具栏中创建拓展项
在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。他们的继承关系为:
二、菜单栏拓展项(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的分割线:
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的菜单效果:
六、其它常用可拓展编辑器模块
类型 | 菜单栏拓展 | 工具栏拓展 |
---|---|---|
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等。还要注意某些模块的加载顺序和时间。