|
编辑器添加扩展
方法
这里只介绍新的方法
- 思路很简单,先定位到想要修改的编辑器位置-菜单/工具栏 位置,然后再进行扩展。
ExtendMenu:在Menus这个TMap中找对应的Menu,找到了就返回,没找到就新建一个,然后加入到Menus容器中。
FindOrAddSection:找到菜单条下对应的菜单分节
AddMenuEntryWithCommandList:为分节添加条目,内部是调用AddEntry实现的。就是传入一个Entry来添加到Blocks数组中。 UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Window");
{
FToolMenuSection& Section = Menu->FindOrAddSection("WindowLayout");
Section.AddMenuEntryWithCommandList(FAddButtonsCommands::Get().PluginAction, PluginCommands);
}
//这个方法用在ToolBar上,因为有InitToolBarButton
UToolMenu* ToolbarMenu = UToolMenus::Get()->ExtendMenu("AssetEditor.BlueprintEditor.ToolBar");
{
FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("PluginTools");
{
FToolMenuEntry& Entry = Section.AddEntry(FToolMenuEntry::InitToolBarButton(FAddButtonsCommands::Get().PluginAction));
Entry.SetCommandList(PluginCommands);
}
}
- 理论上将对应的路径代入上面的方法即可实现编辑器的扩展
- 常见路径
路径查找方法结合蓝图编辑器工具一起介绍 蓝图编辑器工具
- 编辑器工具控件:创建UMG执行写好的的操作
- 编辑器工具蓝图:在指定的父类的右键时可找到该工具
介绍一种用蓝图控件查看编辑器工具路径的方法:
- 创建一个蓝图编辑器控件:并添加一个细节视图,勾选强制隐藏属性可视性
2. 连接如下节点
3. 运行蓝图编辑器控件,可查看到81条路径
Slate控件
为什么有了蓝图控件还要Slate控件?
蓝图控件只能在关卡编辑器里使用,局限性强;Slate可以脱离关卡编辑器单独使用,独立性强。 UMG框架通过蓝图工作,蓝图更接近视觉设计。然而,Slate可以保持干净的代码。 Slate常用语法
SNew:创建SWidget
SAssignNew:创建一个SWidget,并且将SWidget对象额外传递给外部某个变量
SLATE_BEGIN_ARGS和SLATE_END_ARGS:是用来声明当前SWidget类的内部FArguments类。每一个自定义的SWidget类,都得加上这样的声明,否则无法通过编译。
SLATE_ATTRIBUTE: 在自定义的FArguments添加新的属性
+:向对应Array中增加一个新的Slots*成员
[]:用于表示“嵌套”子SWidget。[]符号的预算优先级,要高于+符号
.:用来给New出来的Slate控件添加属性
Slate扩展
class FMySlateModule : public IModuleInterface
{
public:
//注册编辑器的扩展,绑定点击事件,给slate绑定OnSpawnPluginTab
virtual void StartupModule() override;
virtual void ShutdownModule() override;
//点击Btn时,唤醒Tab
void PluginButtonClicked();
private:
//创建编译器扩展
void RegisterMenus();
//绑定到指定的TabName的Raw
TSharedRef<class SDockTab> OnSpawnPluginTab(const class FSpawnTabArgs& SpawnTabArgs);
private:
//插件的命令
TSharedPtr<class FUICommandList> PluginCommands;
};
- 简单的扩展:这里介绍 Lambda 和 委托 两种形式
static const FName MyTab0Name(&#34;MyTab0&#34;);
static const FName MyTab1Name(&#34;MyTab1&#34;);
void FMySlateModule::StartupModule()
{
...
//绑定Lambda
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(MyTab0Name,
FOnSpawnTab::CreateLambda([](const FSpawnTabArgs& SpawnTabArgs) {
FText WidgetText = LOCTEXT(&#34;WindowMyTab0Text&#34;, &#34;MyButton&#34;);
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
// Put your tab content here!
SNew(SButton)
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.OnClicked_Lambda(
[]() {
UE_LOG(LogTemp, Warning, TEXT(&#34;ok&#34;));
return FReply::Handled();
}
)
[
SNew(STextBlock)
.Text(WidgetText)
]
];
}))
.SetDisplayName(LOCTEXT(&#34;MyTab0TabTitle&#34;, &#34;MyTab0&#34;))
.SetMenuType(ETabSpawnerMenuType::Enabled);
//绑定Raw
FGlobalTabmanager::Get()->RegisterNomadTabSpawner(MyTab1Name, FOnSpawnTab::CreateRaw(this, &FMySlateModule::OnSpawnPluginTab1))
.SetDisplayName(LOCTEXT(&#34;FMyTab1TabTitle&#34;, &#34;MyTab1&#34;))
.SetMenuType(ETabSpawnerMenuType::Hidden);
}
void FMySlateModule::PluginButtonClicked()
{
FGlobalTabmanager::Get()->TryInvokeTab(MyTab0Name);
FGlobalTabmanager::Get()->TryInvokeTab(MyTab1Name);
}
TSharedRef<class SDockTab> FMySlateModule::OnSpawnPluginTab1(const FSpawnTabArgs& SpawnTabArgs)
{
TSharedRef<SCheckBox> MyCheckBox = SNew(SCheckBox).IsChecked(ECheckBoxState::Unchecked);
TSharedRef<SEditableText> MyEditableText = SNew(SEditableText).IsEnabled_Lambda(
[MyCheckBox]() {
return MyCheckBox->GetCheckedState() == ECheckBoxState::Checked;
}
);
return SNew(SDockTab)
.TabRole(ETabRole::NomadTab)
[
SNew(SVerticalBox)
+ SVerticalBox::Slot().AutoHeight()
[
MyCheckBox
]
+ SVerticalBox::Slot().AutoHeight()
[
MyEditableText
]
+ SVerticalBox::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SNew(STextBlock)
.Text_Lambda(
[MyEditableText]() {
auto res = MyEditableText->GetText();
return res;
}
)
]
];
}
MyTab1:勾选框被选上时可以开始输入,输入的内容将在中间同步显示
自定义资产
需要做的三个内容:
- 自定义的资产类:(继承UObject),作为自定义资产的数据模型类.
- 相应的Factory类:(继承UFactory),这个工厂类用于被UE4引擎识别,作为可以在ContentBrowser中创建资产(Asset)
- 相应的AssetTypeActions:指定了诸如Asset的名称,应属于的类别,颜色等内容,在模块中实现自定义资产的类型
注意点:
- 在Editor模块的配置cs文件中要添加对Runtime模块和UnrealEd的依赖
- 在插件的uplugin中添加Editor模块
Edotor模块一定是Editor类型,Asset模块根据需求确定类型
- AssetTypeAction类:自定义资产的行为
图源:reference[29]
细致的实现流程请参阅 reference[29],原作代码有两处小错误需注意 细节面板扩展
尝试做了两个模块,一个是细节面板,一个是数据面板(可省略)
- 细节面板
- CustomizeObject:继承自UObject,是我们自定义细节的物体本体,在其上添加所需信息
- TestDetails:继承自IModuleInterface ,主要用于实现模块的构建和关闭,以及自定义属性
- CustomizeWidget:继承自SCompoundWidget,设计细节面板的层级样式
- MyTestDetailCustomization:继承自DetailCustomization ,用于映射到细节面板和实例化
- StructVariableDetail: 继承自IPropertyTypeCustomization,用于detail面板父类下创建子项
- 把细节信息反射到data面板<UCustomizeObject>
- 在OnSpawnPluginTab创建的Tab里添加SCustomizeWidget即可
编辑模式扩展
新建 编辑器模式 插件会帮我们直接生成一个案例,我们看看他的实现
- MyModeModule:负责Module的注册和注销
- MyModeEditorModeToolkit :获取Toolkit的Interface
- MyModeEditorMode:设置Mode工具的名字,初始化Toolkit和Commands ,将Commands和Tools里的ToolBuilder绑定
- MyModeEditorModeCommands:创建命令
- Tools:功能的实现
实现
Reference
★数仅代表对我这篇文章的贡献度,每篇都是非常好的参考资料 [1]★★ UE4给编辑器添加菜单栏(Menu),菜单条(MenuBar),工具条(ToolBar)——套路与源码分析
[2]★ Unreal Engine 4(虚幻引擎4)编辑器开发基础课程| ABOUTCG视频教程
[3]★★★ Shijiening/ToolBox: UE4 编辑器工具 (github.com)
[4]★★★★★ 【合集】UE4插件与Slate_哔哩哔哩_bilibili
[5]★★★ Unreal Engine 5 - Writing Plugins in C++ - YouTube
[6]★★ 扬·沃索克 |UE4 #1中的编辑器插件 – 简介 (wlosok.cz)
[7]★★★★★ 【UE4】Blueprintだけで、Editor上にメニューを追加する【★★★】 | キンアジのブログ
[8]★★ (69条消息) UE4 Slate 特殊语法_写文档试验号的博客-CSDN博客
[9]★★★★ (69条消息) UE中创建自定义Asset类_天才宝藏的博客-CSDN博客_ue4 自定义asset
[10]★★ UE4拓展Details面板 - 知乎 (zhihu.com) |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
×
|