UE4 插件擴展引擎工具欄

  UE4 做爲遊戲引擎,已經提供了很是強大的遊戲開發的API。做爲遊戲製做者來說,咱們須要一些專用的功能輔助咱們更好的開發遊戲,而不是僅僅從構建遊戲邏輯出發。所以也就有了擴展編輯器功能的這個想法,還好 UE4 提供了許多編輯器的接口,便於咱們給編輯器添加咱們的功能。編輯器

  下面是一個擴展編輯器工具欄的例子,咱們增長了一個本身的按鈕。這個在新建插件,選擇 Editor Standalone Window 就能夠實現此效果。我這裏新建一個空的插件,來實現這個效果,以便於理解。ide

  

  UE4 是以模塊的功能構建項目,插件也是一種模塊,便於移植更新,因此咱們將代碼以插件結構的形式呈現。函數

  首先,新建一個空白插件 ExtendedToolBarPlugin ,如紅色方框內容工具

  

  ***.uplugin 是插件描述文件  ui

{
    "FileVersion": 3,
    "Version": 1,
    "VersionName": "1.0",
    "FriendlyName": "ExtendedToolBarPlugin",
    "Description": "",
    "Category": "Other",
    "CreatedBy": "Jqm",
    "CreatedByURL": "",
    "DocsURL": "",
    "MarketplaceURL": "",
    "SupportURL": "",
    "CanContainContent": true,
    "IsBetaVersion": false,
    "Installed": false,
    "Modules": [
        {
            "Name": "ExtendedToolBarPlugin",//插件的名字
            "Type": "Editor",//插件的類型,修改成Editor .
            "LoadingPhase": "Default"
        }
    ]
}

  ***.Build.cs 是插件中模塊 ExtendedToolBarPlugin 的描述,定義了該模塊的引用頭文件信息,引用庫信息,以及擴展依賴等。稍後,咱們主要會在裏面添加模塊依賴,以便於咱們引用編輯器的 API。this

  ***.h 和 ***.cpp 定義了該模塊和引擎的接口。spa

//***.h
class
FExtendedToolBarPluginModule : public IModuleInterface { public: /** IModuleInterface implementation */ //當模塊被加載時調用 virtual void StartupModule() override; //當模塊被卸載時調用 virtual void ShutdownModule() override;

  // 新增函數
  void ButtonClicked();

   // 向工具欄中添加按鈕
   void AddToolbarExtension(FToolBarBuilder& Builder);插件


  TSharedPtr<class FUICommandList> ButtonClickCommands; };

void FExtendedToolBarPluginModule::AddToolbarExtension(FToolBarBuilder& Builder)code

 
 

{
  Builder.AddToolBarButton(FWindowTestCommands::Get().
OpenPluginWindow);blog

}



   以上就是整個插件的結構,編譯成功插件就行正常運行。可是僅僅是插件正常運行,並未加入任何功能。

  咱們開始對 Editor Standalone Window 的分析,發如今模塊初始化函數 StartupModule() 中,獲取了編輯器模塊 FLevelEditorModule& LevelEditorModule, 而後新增長了一個擴展 MakeShareable(new FExtender()) ,而後將新增長的擴展加入到編輯器的工具欄管理模塊中。 重點是這個新增長的擴展,設置了一些屬性,標記擴展的是編輯器的哪一部分,傳遞了一個命令,這個命令用來響應觸發這個按鈕的消息,至關於一個回調,等信息。

  首先,咱們來構建這個擴展所須要的內容。

  咱們第一步建立這個命令:在插件中新建一個類 FWindowTestCommands,該類繼承至一個模板類TCommands,該模板類以本身的定義做爲模板,而且提供了註冊命令和卸載的一系列方法。因此咱們繼承它就能夠實現編輯器所須要的命令。

 

// ***.h
//
Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Framework/Commands/Commands.h" #include "WindowTestStyle.h" class FWindowTestCommands : public TCommands<FWindowTestCommands> { public: FWindowTestCommands() : TCommands<FWindowTestCommands>(TEXT("WindowTest"), NSLOCTEXT("Contexts", "WindowTest", "WindowTest Plugin"), NAME_None, FWindowTestStyle::GetStyleSetName()) { } // TCommands<> interface virtual void RegisterCommands() override; public: TSharedPtr< FUICommandInfo > OpenPluginWindow; };
// ***.cpp
//
Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. #include "WindowTestCommands.h" #define LOCTEXT_NAMESPACE "FWindowTestModule" void FWindowTestCommands::RegisterCommands() { UI_COMMAND(OpenPluginWindow, "WindowTest", "Bring up WindowTest window", EUserInterfaceActionType::Button, FInputGesture()); } #undef LOCTEXT_NAMESPACE
 TCommands<FWindowTestCommands>(TEXT("WindowTest"), NSLOCTEXT("Contexts", "WindowTest", "WindowTest Plugin"), NAME_None, FWindowTestStyle::GetStyleSetName())傳遞了4個參數,分別是命令的名字,命令的描述,命令的的上下級,命令的風格。
 RegisterCommands()將命令進行註冊。

命令的風格。再 RegisterCommands()註冊編輯器的時候,有個枚舉類型 EUserInterfaceActionType::Button ,說明是個按鈕,那麼這個風格說的就是響應按鈕的這個風格,所以,咱們在構造命令是也傳入的一個風格。如今咱們新建一個風格,傳入給命令。

在插件中新建一個類 FWindowTestStyle ,這個類全是靜態函數。它提供了風格的建立,銷燬等方法。

// ***.h
//
Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Styling/SlateStyle.h" /** */ class FWindowTestStyle { public: static void Initialize(); static void Shutdown(); /** reloads textures used by slate renderer */ static void ReloadTextures(); /** @return The Slate style set for the Shooter game */ static const ISlateStyle& Get(); static FName GetStyleSetName(); private: static TSharedRef< class FSlateStyleSet > Create(); private: static TSharedPtr< class FSlateStyleSet > StyleInstance; };

 

在建立風格時,他尋找了插件下面的資源圖片做爲本身的Icon。

// ***.cpp
//
Copyright 1998-2018 Epic Games, Inc. All Rights Reserved. #include "WindowTestStyle.h" #include "Styling/SlateStyleRegistry.h" #include "Framework/Application/SlateApplication.h" #include "SlateGameResources.h" #include "IPluginManager.h" TSharedPtr< FSlateStyleSet > FWindowTestStyle::StyleInstance = NULL; void FWindowTestStyle::Initialize() { if (!StyleInstance.IsValid()) { StyleInstance = Create(); FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance); } } void FWindowTestStyle::Shutdown() { FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); ensure(StyleInstance.IsUnique()); StyleInstance.Reset(); } FName FWindowTestStyle::GetStyleSetName() { static FName StyleSetName(TEXT("ExtendedToolBarStyle")); return StyleSetName; } #define IMAGE_BRUSH( RelativePath, ... ) FSlateImageBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) #define BOX_BRUSH( RelativePath, ... ) FSlateBoxBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) #define BORDER_BRUSH( RelativePath, ... ) FSlateBorderBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) #define TTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".ttf") ), __VA_ARGS__ ) #define OTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".otf") ), __VA_ARGS__ ) const FVector2D Icon16x16(16.0f, 16.0f); const FVector2D Icon20x20(20.0f, 20.0f); const FVector2D Icon40x40(40.0f, 40.0f); TSharedRef< FSlateStyleSet > FWindowTestStyle::Create() { TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("ExtendedToolBarStyle")); Style->SetContentRoot(IPluginManager::Get().FindPlugin("ExtendedToolBarPlugin")->GetBaseDir() / TEXT("Resources")); Style->Set("ExtendedToolBarPlugin.ButtonClick", new IMAGE_BRUSH(TEXT("ButtonIcon_40x"), Icon40x40)); return Style; } #undef IMAGE_BRUSH #undef BOX_BRUSH #undef BORDER_BRUSH #undef TTF_FONT #undef OTF_FONT void FWindowTestStyle::ReloadTextures() { if (FSlateApplication::IsInitialized()) { FSlateApplication::Get().GetRenderer()->ReloadTextureResources(); } } const ISlateStyle& FWindowTestStyle::Get() { return *StyleInstance; }

 

  如今,基本上全部資源都準備完畢,就下來就開始寫邏輯,將整個流程實現。

  在 ExtendedToolBarPlugin 模塊中,初始化模塊階段,也就是 StartupModule() 函數中,咱們開始建立風格和命令:

    // 註冊編輯器插件風格
    FWindowTestStyle::Initialize();
    FWindowTestStyle::ReloadTextures();

    // 註冊編輯器插件命令
    FWindowTestCommands::Register();

  建立插件命令 ExtendedToolBarCommands,這個在模塊類定義,

// 建立插件編輯器命令
    ExtendedToolBarCommands = MakeShareable(new FUICommandList);
    ExtendedToolBarCommands->MapAction(FWindowTestCommands::Get().OpenPluginWindow, FExecuteAction::CreateRaw(this, &FExtendedToolBarPluginModule::ButtonClicked), FCanExecuteAction());

  而後,加入到編輯器中,

  AddToolBarExtension 第一個參數:是指添加到 工具欄的 Settings 部分;

  第二個參數是在這個部分的位置,前面,後面或第一個;

  第三個參數,是前面建立的命令,傳遞進去;

  第四個參數,是添加到編輯器的按鈕;

    FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
    {
        TSharedPtr<FExtender> ToolbarExtender = MakeShareable(new FExtender);
        ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, JqmToolsEditorCommands, FToolBarExtensionDelegate::CreateRaw(this, &FExtendedToolBarModule::AddToolbarExtension));

        LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);
    }

  到此,整個流程走完。

  總結一下,按照順序,應該是初始化模塊入口函數裏:

  1.建立風格

  2.建立命令

  3.綁定命令

  4.建立工具欄擴展

  5.添加的到工具欄

相關文章
相關標籤/搜索