
创建成功效果如下(我名字为Test):

插件名叫SimpleWindow,所以生成4个文件夹名为:Test.h、TestCommand.h、TestStyle.h及其cpp,记忆Test.Build.cs

Test类:为插件主类,插件的入口和出口都在此类中
TestCommand类:注册一个OpenPluginWindow的命令
TestStyle类:定义UI样式的类
- // Copyright 1998-2017 Epic Games, Inc. All Rights Reserved.
-
- #include "Test.h"
- #include "TestStyle.h"
- #include "TestCommands.h"
- #include "LevelEditor.h"
- #include "Widgets/Docking/SDockTab.h"
- #include "Widgets/Layout/SBox.h"
- #include "Widgets/Text/STextBlock.h"
- #include "Framework/MultiBox/MultiBoxBuilder.h"
-
- static const FName TestTabName("Test");
-
- #define LOCTEXT_NAMESPACE "FTestModule"
-
- void FTestModule::StartupModule()
- {
- // This code will execute after your module is loaded into memory; the exact timing is specified in the .uplugin file per-module
-
- FTestStyle::Initialize();//初始化UI样式
- FTestStyle::ReloadTextures();//初始化UI样式
-
- FTestCommands::Register();//注册命令
-
- PluginCommands = MakeShareable(new FUICommandList);//实例化一个命令
-
- PluginCommands->MapAction(//将实例化的命令进行绑定,且绑定到函数FTestModule::PluginButtonClicked
- FTestCommands::Get().OpenPluginWindow,
- FExecuteAction::CreateRaw(this, &FTestModule::PluginButtonClicked),
- FCanExecuteAction());
-
- FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");//获取LevelEditor模块的引用
-
- {
- TSharedPtr<FExtender> MenuExtender = MakeShareable(new FExtender());//创建一个菜单扩展,并把它添加到场景编辑器中
- MenuExtender->AddMenuExtension("WindowLayout", EExtensionHook::After, PluginCommands, FMenuExtensionDelegate::CreateRaw(this, &FTestModule::AddMenuExtension));
-
- LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(MenuExtender);
- }
-
- {
- TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);//创建一个菜单扩展,并添加到工具栏
- ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FTestModule::AddToolbarExtension));
-
- LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);
- }
-
- FGlobalTabmanager::Get()->RegisterNomadTabSpawner(TestTabName, FOnSpawnTab::CreateRaw(this, &FTestModule::OnSpawnPluginTab))//注册一个Tab容器
- .SetDisplayName(LOCTEXT("FTestTabTitle", "Test"))
- .SetMenuType(ETabSpawnerMenuType::Hidden);
- }
-
- void FTestModule::ShutdownModule()
- {
- // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading,
- // we call this function before unloading the module.
- FTestStyle::Shutdown();
-
- FTestCommands::Unregister();
-
- FGlobalTabmanager::Get()->UnregisterNomadTabSpawner(TestTabName);
- }
-
- TSharedRef<SDockTab> FTestModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
- {
- FText WidgetText = FText::Format(
- LOCTEXT("WindowWidgetText", "Add code to {0} in {1} to override this window's contents"),
- FText::FromString(TEXT("FTestModule::OnSpawnPluginTab")),
- FText::FromString(TEXT("Test.cpp"))
- );
-
- return SNew(SDockTab)
- .TabRole(ETabRole::NomadTab)
- [
- // Put your tab content here!
- SNew(SBox)
- .HAlign(HAlign_Center)
- .VAlign(VAlign_Center)
- [
- SNew(STextBlock)
- .Text(WidgetText)
- ]
- ];
- }
-
- void FTestModule::PluginButtonClicked()
- {
- FGlobalTabmanager::Get()->InvokeTab(TestTabName);
- }
-
- void FTestModule::AddMenuExtension(FMenuBuilder& Builder)
- {
- Builder.AddMenuEntry(FTestCommands::Get().OpenPluginWindow);
- }
-
- void FTestModule::AddToolbarExtension(FToolBarBuilder& Builder)
- {
- Builder.AddToolBarButton(FTestCommands::Get().OpenPluginWindow);
- }
-
- #undef LOCTEXT_NAMESPACE
-
- IMPLEMENT_MODULE(FTestModule, Test)
在工具栏点击按钮时,因为以下代码让ToolbarExtension与PluginCommands关联,PluginCommands执行的函数是&FTestModule::PluginButtonClicked,所以当点击按钮后,执行的是该函数
- FTestCommands::Register();//注册命令
-
- PluginCommands = MakeShareable(new FUICommandList);//实例化一个命令
-
- PluginCommands->MapAction(//将实例化的命令进行绑定,且绑定到函数FTestModule::PluginButtonClicked
- FTestCommands::Get().OpenPluginWindow,
- FExecuteAction::CreateRaw(this, &FTestModule::PluginButtonClicked),
- FCanExecuteAction());
-
- FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");//获取LevelEditor模块的引用
-
- TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);//创建一个菜单扩展,并添加到工具栏
- ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FTestModule::AddToolbarExtension));
-
- LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);
PluginButtonClicked里调用了FGlobalTabmanager的Invoke函数,因为在StartupModule里,已经注册了Tab了,InvokeTab函数会启动这个Tab,而Tab在注册时已经绑定了&FTestModule::OnSpawnPluginTab这个函数,所以InvokeTab去调用该函数去了
- FGlobalTabmanager::Get()->RegisterNomadTabSpawner(TestTabName, FOnSpawnTab::CreateRaw(this, &FTestModule::OnSpawnPluginTab))//注册一个Tab容器
- .SetDisplayName(LOCTEXT("FTestTabTitle", "Test"))
- .SetMenuType(ETabSpawnerMenuType::Hidden);
-
- void FTestModule::PluginButtonClicked()
- {
- FGlobalTabmanager::Get()->InvokeTab(TestTabName);
- }
在OnSpawnPluginTab内部,实现了具体UI
- TSharedRef<SDockTab> FTestModule::OnSpawnPluginTab(const FSpawnTabArgs& SpawnTabArgs)
- {
- FText WidgetText = FText::Format(
- LOCTEXT("WindowWidgetText", "Add code to {0} in {1} to override this window's contents"),
- FText::FromString(TEXT("FTestModule::OnSpawnPluginTab")),
- FText::FromString(TEXT("Test.cpp"))
- );
-
- return SNew(SDockTab)
- .TabRole(ETabRole::NomadTab)
- [
- // Put your tab content here!
- SNew(SBox)
- .HAlign(HAlign_Center)
- .VAlign(VAlign_Center)
- [
- SNew(STextBlock)
- .Text(WidgetText)
- ]
- ];
- }