13. 添加module的流程
右键.uproject文件 添加新的模块
{
"FileVersion": 3,
"EngineAssociation": "4.16",
"Category": "",
"Description": "",
"Modules": [
{
"Name": "UE4Cook",
"Type": "Runtime",
"LoadingPhase": "Default",
"AdditionalDependencies": [
"Engine",
"CoreUObject"
]
},
{
"Name": "UE4CookTestEditor", //新模块名称
"Type": "Editor", //运行模式 Runtime 表示 既在editor模式下运行 又在发布版运行
"LoadingPhase": "PostEngineInit", //模块加载时机
"AdditionalDependencies": [
"Engine",
"CoreUObject"
]
}
]
}
添加配置文件
在Source下 参照原有的文件接口 添加UE4CookTestEditor 文件夹 里面相应创建xx.h xx.build.cs xx.cpp文件
.build.cs
using UnrealBuildTool;
public class UE4CookTestEditor : ModuleRules
{
public UE4CookTestEditor(ReadOnlyTargetRules Target) : base(Target)
{
PublicDependencyModuleNames.AddRange(new string[] {"Core", "CoreUObject", "Engine", "InputCore", "RHI","RenderCore", "ShaderCore" });
PublicDependencyModuleNames.Add("UE4Cook"); //主模块
PrivateDependencyModuleNames.AddRange(new string[] {"UnrealEd" });
}
}
其中。h文件
#pragma once
#include "CoreMinimal.h"
#include "Engine.h"
#include "ModuleManager.h"
#include "UnrealEd.h" //为了使用Editor相关的函数 可以不加
class FUE4CookTestEditorModule: public IModuleInterface
{
};
.cpp文件
#include "UE4CookTestEditor.h"
#include "Modules/ModuleManager.h"
IMPLEMENT_PRIMARY_GAME_MODULE( FUE4CookTestEditorModule, UE4CookTestEditor); //此处的名称要与。uproject中配置的名称保持一致
添加完以上文件后 右键。uproject 重新生成vsstudio文件
编辑UE4CookTestEditor.Target.cs
using UnrealBuildTool;
using System.Collections.Generic;
public class UE4CookEditorTarget : TargetRules
{
public UE4CookEditorTarget(TargetInfo Target) : base(Target)
{
Type = TargetType.Editor;
ExtraModuleNames.AddRange( new string[] { "UE4CookTestEditor" } );
}
}
编译程序并运行 点开/developTools/Modules 查看自定义的module是否正确添加
主要要点 一定要确保模块名称在文件名 。build.cs .h 。cpp中的一致性 模块创建失败多是由于名称不一致引起的
14. 添加工具ui到Editor中
editor的ui是通过TCommand的方式进行声明
在。build.cs中
publicDependencyModuleNames 添加Slate模块
添加CookbookCommands.h
#pragma once
#include "Commands.h"
#include "EditorStyleSet.h"
class FCookbookCommands : public TCommands<FCookbookCommands>
{
public:
FCookbookCommands() :TCommands<FCookbookCommands>(FName(TEXT("UE4_Cookbook")), //command 名称
FText::FromString("Cookbook Commands"), // 提示信息
NAME_None,
//配合提示信息的 参数
FEditorStyle::GetStyleSetName())
{};
virtual void RegisterCommands() override;
TSharedPtr<FUICommandInfo> myButton;
};
添加CookbookCommands.cpp
#include "UE4CookTestEditor.h"
#include "Commands.h"
#include "CookbookCommands.h"
void FCookbookCommands::RegisterCommands()
{
#define LOCTEXT_NAMESPACE ""
UI_COMMAND(myButton, "Cookbook", "Demo Cookbook Toolbar command", EUserInterfaceActionType::Button, FInputGesture()); //创建button 保存到myButton中
#undef LOCTEXT_NAMESPACE
}
在Editor module类中 重写StartupModule ShutdownModule函数 在其中将之前定义的command 绑定到具体的事件和ui中
editor.h文件
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "Engine.h"
#include "ModuleManager.h"
#include "UnrealEd.h"
#include "MainFrame.h" //需要在。build.cs中添加Mainframe模块
#include "CookbookCommands.h"
#include "MultiBoxExtender.h"
class FUE4CookTestEditorModule: public IModuleInterface
{
public:
virtual void StartupModule() override;
virtual void ShutdownModule() override;
TSharedPtr<FExtender> ToolbarExtender; //菜单类 可以用来拓展右键菜单 和工具栏菜单
TSharedPtr<const FExtensionBase> Extension; //拓展类 存储添加菜单的结果
//按钮点击事件
void MyButton_Clicked()
{
TSharedPtr<SWindow> CookbookWindow = SNew(SWindow)
.Title(FText::FromString(TEXT("Co Window")))
.ClientSize(FVector2D(800, 400))
.SupportsMaximize(false)
.SupportsMinimize(false);
IMainFrameModule& mainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
if (mainFrameModule.GetParentWindow().IsValid())
{
FSlateApplication::Get().AddWindowAsNativeChild(CookbookWindow, mainFrameModule.GetParentWindow().ToSharedRef())
}
else
{
FSlateApplication::Get().AddWindow(CookbookWindow);
}
};
//添加到工具栏的按钮添加执行函数
void AddToolbarExtension(FToolBarBuilder& builder)
{
//创建按钮图标
FSlateIcon iconBrush = FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.ViewOptions", "LevelEditor.ViewOptions.Small");
//添加按钮 第一个参数是
builder.AddToolBarButton(FCookbookCommands::Get().myButton, NAME_None, FText::FromString("btn"), FText::FromString("Click to display", iconBrush, NAME_None));
};
};
editor.cpp文件
// Fill out your copyright notice in the Description page of Project Settings.
#include "UE4CookTestEditor.h"
#include "Modules/ModuleManager.h"
#include "ILevelEditor.h"
#include "SlateBasics.h"
IMPLEMENT_GAME_MODULE(FUE4CookTestEditorModule, UE4CookTestEditor);
void FUE4CookTestEditorModule::StartupModule()
{
FCookbookCommands::Register(); //注册自定义command
TSharedPtr<FUICommandList> CommandList = MakeShareable(new FUICommandList()); //创建commandlist 保存我们绑定的事件
//绑定按钮事件 第一个参数是我们创建的按钮 第二个参数是按钮的执行回调 第三个参数是执行前的判断回调 为true的画才可以执行按钮事件 这里使用预定义的回调 始终返回true
CommandList->MapAction(FCookbookCommands::Get().myButton, FExecuteAction::CreateRaw(this, &FUE4CookTestEditorModule::MyButton_Clicked), FCanExecuteAction());
ToolbarExtender = MakeShareable(new FExtender()); //创建菜单类 可以用来拓展右键菜单 和工具栏菜单
//添加按钮到工具栏 第一个参数是添加的位置 可以通过Editor Setting/ Generay / miscellaneous /display uiextension points 获得菜单的位置 第二个参数是具体的位置在前
Extension = ToolbarExtender->AddToolBarExtension("Compile", EExtensionHook::Before, CommandList, FToolBarExtensionDelegate::CreateRaw(this,
&FUE4CookTestEditorModule::AddToolbarExtension));
//将工具栏添加到editor中
FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked<FLevelEditorModule>("LevelEditor");
LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender);
}
void FUE4CookTestEditorModule::ShutdownModelu()
{
//模块关闭时 移除拓展
ToolbarExtender->RemoveExtension(Extension.ToSharedRef());
Extension.Reset();
ToolbarExtender.Reset();
}
.build.cs
// Fill out your copyright notice in the Description page of Project Settings.
using UnrealBuildTool;
public class UE4CookTestEditor : ModuleRules
{
public UE4CookTestEditor(ReadOnlyTargetRules Target) : base(Target)
{
PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "RHI", "RenderCore", "ShaderCore", "Slate", "SlateCore", "MainFrame", "EditorStyle", });
PublicDependencyModuleNames.Add("UE4Cook");
PrivateDependencyModuleNames.AddRange(new string[] { "UnrealEd" });
}
}
添加菜单按钮
与普通按钮不一样的地方
1.在。h的Add函数中 调用builder.AddMenuEntry
2.在。cpp extender的extender->AddMenuExtension 变成AddMenuExtension
3.LevelEditorModule.GetMenuExtensibilityManager()->AddExtender(ToolbarExtender);
添加窗口
可以通过windows/develop tools/widget reflector 点击PickLiveWidget 获得窗口层级
TSharedRef<SWindow> CookbookWindow = SNew(SWindow) //创建一个SWindow类型的Slate
.Title(FText::FromString(TEXT("Cookbook Window"))) //设置window的属性
.ClientSize(FVector2D(800, 400))
.SupportsMaximize(false)
.SupportsMinimize(false)
[ //在【】中添加要拜访到该slot的ui window只有能添加一个widget
SNew(SVerticalBox)
+ SVerticalBox::Slot() //通过重载运算符 + 获得一个slot
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text(FText::FromString(TEXT("Hello from Slate")))
]
];
IMainFrameModule& mainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
if (mainFrameModule.GetParentWindow().IsValid())
{
FSlateApplication::Get().AddWindowAsNativeChild(CookbookWindow, mainFrameModule.GetParentWindow().ToSharedRef());
}
else
{
FSlateApplication::Get().AddWindow(CookbookWindow);
}
15 创建ue4可用的新的资源类型
创建继承自UObject 自定义类
创建继承自UFactory 的自定义类 重写其中的FactoryCreateNew方法 在方法中创建我们自定义的类型
自定义的类型 可以通过在content中 右键 miscellaneous中查询到
。cpp文件
// Fill out your copyright notice in the Description page of Project Settings.
#include "CustomAssetFactory.h"
#include "MyCustomAsset.h"
UCustomAssetFactory::UCustomAssetFactory():Super()
{
bCreateNew = true;
bEditAfterNew = true;
SupportedClass = UMyCustomAsset::StaticClass();
}
UObject* UCustomAssetFactory::FactoryCreateNew(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn, FName CallingContext)
{
auto NewObjectAsset = NewObject<UMyCustomAsset>(InParent, InClass, InName, Flags);
return NewObjectAsset;
}
16 创建自定义资源的右键菜单
创建菜单类 继承自FAssetTypeActions_Base
.h文件
#pragma once
#include "AssetTypeActions_Base.h"
class FMyCustomAssetActions :public FAssetTypeActions_Base
{
public:
virtual bool HasActions(const TArray<UObject*>& InObjects)const override; //系统调用 确认该类型是否有action
virtual void GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& menuBuilder) override; //如果上面返回true 那么调用下面 添加菜单项
virtual FText GetName() const override; //资源在缩略图模式下 鼠标的tip提示
virtual UClass* GetSupportedClass() const override; //资源缩略图的颜色
virtual FColor GetTypeColor() const override;
virtual uint32 GetCategories() override;
void MyCustomAssetContent_Clicked();
};
.cpp文件
#include "UE4CookTestEditor.h"
#include "MyCustomAssetActions.h"
#include "MyCustomAsset.h"
bool FMyCustomAssetActions::HasActions(const TArray<UObject*>& InObjects) const
{
return true;
}
void FMyCustomAssetActions::GetActions(const TArray<UObject*>& InObjects, FMenuBuilder& menuBuilder)
{
menuBuilder.AddMenuEntry(FText::FromString("CustomAssetAction"),
FText::FromString("Action from Cook"),
FSlateIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.ViewOptions"),
FUIAction(FExecuteAction::CreateRaw(this, &FMyCustomAssetActions::MyCustomAssetContent_Clicked),
FCanExecuteAction())
);
}
uint32 FMyCustomAssetActions::GetCategories()
{
return EAssetTypeCategories::Misc;
}
FText FMyCustomAssetActions::GetName() const
{
return FText::FromString(TEXT("My Custom Asset"));
}
UClass* FMyCustomAssetActions::GetSupportedClass() const
{
return UMyCustomAsset::StaticClass();
}
FColor FMyCustomAssetActions::GetTypeColor() const
{
return FColor::Emerald;
}
void FMyCustomAssetActions::MyCustomAssetContent_Clicked()
{
TSharedRef<SWindow> CookbookWindow = SNew(SWindow)
.Title(FText::FromString(TEXT("Cookbook Window")))
.ClientSize(FVector2D(800, 400))
.SupportsMaximize(false)
.SupportsMaximize(false);
IMainFrameModule& MainFrameModule = FModuleManager::LoadModuleChecked<IMainFrameModule>(TEXT("MainFrame"));
if (MainFrameModule.GetParentWindow().IsValid())
{
FSlateApplication::Get().AddWindowAsNativeChild(CookbookWindow, MainFrameModule.GetParentWindow().ToSharedRef());
}
else
{
FSlateApplication::Get().AddWindow(CookbookWindow);
}
}
在Editor Module startModule中
IAssetTools& AssetTools = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools").Get();
auto Actions = MakeShareable(new FMyCustomAssetActions);
AssetTools.RegisterAssetTypeActions(Actions);
删除的时候 在shutdownModule中
//删除command
if (DisplayTestCommand)
{
IConsoleManager::Get().UnregisterConsoleObject(DisplayTestCommand);
DisplayTestCommand = nullptr;
}
工程代码的下载地址:http://download.csdn.net/download/maxiaosheng521/10230118