当前位置: 首页 > news >正文

【UE5】新建Editor Standalone Window插件,之前(或当前)创建插件的按钮消失(被顶掉/占用)的问题

问题描述

当你在同一个项目里先后新建两个Editor Standalone Window的插件模板:

然后你会发现,菜单栏里并不会出现两个插件入口。先前创建的插件入口消失了。后一个插件把前一个的入口按钮给顶掉了:

之前:

新建一个TestToolBarWiondow2后:

此时发现TestToolBarWindow的按钮消失了(但是该插件并没有被我禁用)

或者新建的按钮消失了(如果没有指定依赖顺序和配置加载阶段之类的,那么插件会按照字典序先后加载。最终留下的按钮是字典序最后面的那个。。。)

原因分析

先来看下这个插件模板的按钮注册大致流程,以TestToolBarWindow为例,注册菜单的核心逻辑在TestToolBarWindow.cpp里的这个函数:

void FTestToolbarWindowModule::RegisterMenus()
{// Owner will be used for cleanup in call to UToolMenus::UnregisterOwnerFToolMenuOwnerScoped OwnerScoped(this);{UToolMenu* Menu = UToolMenus::Get()->ExtendMenu("LevelEditor.MainMenu.Window");{FToolMenuSection& Section = Menu->FindOrAddSection("WindowLayout");Section.AddMenuEntryWithCommandList(FTestToolbarWindowCommands::Get().OpenPluginWindow, PluginCommands);}}{UToolMenu* ToolbarMenu = UToolMenus::Get()->ExtendMenu("LevelEditor.LevelEditorToolBar");{FToolMenuSection& Section = ToolbarMenu->FindOrAddSection("Settings");{FToolMenuEntry& Entry = Section.AddEntry(FToolMenuEntry::InitToolBarButton(FTestToolbarWindowCommands::Get().OpenPluginWindow));Entry.SetCommandList(PluginCommands);}}}
}

它这边直接写死了获取的"LevelEditor.MainMenu.Window"这个Menu下的名为"WindowLayout"的Section

FToolMenuSection& Section = Menu->FindOrAddSection("WindowLayout");

所以可以得知,我们创建的两个插件的按钮都是默认写到同一个Menu的同一个Section下的。

然而:

一个ToolMenu下会有多个Section(可以当成是逻辑分组),然后每个Section里会有Entry(可以直观理解为按钮入口);当你在同一个Section里Add一个已经有同名Entry的Entry,那么会把之前的同名的Entry顶替掉。

而我们注册的按钮的Entry的名字是由啥决定的呢?

点进AddMenuEntryWithCommandList,一路查看定义(这边就不贴全代码了),会发现Entry使用的名字,如果没有额外指定的话,实际上就是这个const TSharedPtr< const FUICommandInfo >& InCommandCommandName字段:

FToolMenuEntry& FToolMenuSection::AddMenuEntryWithCommandList(const TSharedPtr< const FUICommandInfo >& InCommand, const TSharedPtr< const FUICommandList >& InCommandList, const TAttribute<FText>& InLabelOverride, const TAttribute<FText>& InToolTipOverride, const TAttribute<FSlateIcon>& InIconOverride, const FName InTutorialHighlightName, const TOptional<FName> InNameOverride)
{return AddEntry(FToolMenuEntry::InitMenuEntryWithCommandList(InCommand, InCommandList, InLabelOverride, InToolTipOverride, InIconOverride, InTutorialHighlightName, InNameOverride));
}

即我们的FTestToolbarWindowCommandsOpenPluginWindowCommandName字段。

然后我们来追溯下这个字段是怎么设置的。

来到TestToolbarWindowCommands.cpp这里:

void FTestToolbarWindowCommands::RegisterCommands()
{UI_COMMAND(OpenPluginWindow, "TestToolbarWindow", "Bring up TestToolbarWindow window", EUserInterfaceActionType::Button, FInputChord());
}

看看UI_COMMAND宏的定义:

#define UI_COMMAND( CommandId, FriendlyName, InDescription, CommandType, InDefaultChord, ... ) \MakeUICommand_InternalUseOnly( this, CommandId, TEXT(LOCTEXT_NAMESPACE), TEXT(#CommandId), TEXT(#CommandId) TEXT("_ToolTip"), "." #CommandId, TEXT(FriendlyName), TEXT(InDescription), CommandType, InDefaultChord, ## __VA_ARGS__ );

再进去一层看MakeUICommand_InternalUseOnly的定义:

void MakeUICommand_InternalUseOnly( FBindingContext* This, TSharedPtr< FUICommandInfo >& OutCommand, const TCHAR* InSubNamespace, const TCHAR* InCommandName, const TCHAR* InCommandNameUnderscoreTooltip, const ANSICHAR* DotCommandName, const TCHAR* FriendlyName, const TCHAR* InDescription, const EUserInterfaceActionType CommandType, const FInputChord& InDefaultChord, const FInputChord& InAlternateDefaultChord)
{static const FString UICommandsStr(TEXT("UICommands"));const FString Namespace = InSubNamespace && FCString::Strlen(InSubNamespace) > 0 ? UICommandsStr + TEXT(".") + InSubNamespace : UICommandsStr;FUICommandInfo::MakeCommandInfo(This->AsShared(),OutCommand,InCommandName,FText::AsLocalizable_Advanced( Namespace, InCommandName, FriendlyName ),FText::AsLocalizable_Advanced( Namespace, InCommandNameUnderscoreTooltip, InDescription ),FSlateIcon( This->GetStyleSetName(), ISlateStyle::Join( This->GetContextName(), DotCommandName ) ),CommandType,InDefaultChord,InAlternateDefaultChord);
}

再进去一层看看MakeCommandInfo的定义,即可看到CommandName的赋值:

void FUICommandInfo::MakeCommandInfo( const TSharedRef<class FBindingContext>& InContext, TSharedPtr< FUICommandInfo >& OutCommand, const FName InCommandName, const FText& InCommandLabel, const FText& InCommandDesc, const FSlateIcon& InIcon, const EUserInterfaceActionType InUserInterfaceType, const FInputChord& InDefaultChord, const FInputChord& InAlternateDefaultChord, const FName InBundle)
{ensureMsgf( !InCommandLabel.IsEmpty(), TEXT("Command labels cannot be empty") );LLM_SCOPE_BYTAG(UI_Slate);OutCommand = MakeShareable( new FUICommandInfo( InContext->GetContextName() ) );OutCommand->CommandName = InCommandName;OutCommand->Label = InCommandLabel;OutCommand->Description = InCommandDesc;OutCommand->Icon = InIcon;OutCommand->UserInterfaceType = InUserInterfaceType;OutCommand->DefaultChords[static_cast<uint8>(EMultipleKeyBindingIndex::Primary)] = InDefaultChord;OutCommand->DefaultChords[static_cast<uint8>(EMultipleKeyBindingIndex::Secondary)] = InAlternateDefaultChord;OutCommand->Bundle = InBundle;FInputBindingManager::Get().CreateInputCommand( InContext, OutCommand.ToSharedRef() );
}

那么真相已经浮出水面。 从MakeCommandInfo回溯可以得知,一个CommandCommandName就是UI_COMMAND宏的第一个变量的这个变量名!比如这里:

UI_COMMAND(OpenPluginWindow, "TestToolbarWindow", "Bring up TestToolbarWindow window", EUserInterfaceActionType::Button, FInputChord());

那这个Command的CommandNanme就是"OpenPluginWindow"

 

那怪不得会串号。。。。。。

 

解决方案

建议创建菜单插件的时候给你自己的插件建立一个独有的Section名字,来替换掉这里的"WindowLayout"

FToolMenuSection& Section = Menu->FindOrAddSection("WindowLayout");

 

 

http://www.dtcms.com/a/450042.html

相关文章:

  • h5做的网站如何连接数据库wordpress上传图片错误媒体库错误
  • 预约记录关联查询接口说明
  • 免得做网站云浮新增病例详情
  • <从零基础到精通JavaScript>1.1 JavaScript 运行环境
  • 青浦专业网站建设企业网站最下面的那栏叫啥
  • 每日一个C语言知识:C 数据类型
  • 实验二十 GaussDB逻辑备份恢复实验
  • 中英文网站制作wordpress表
  • 开源 网站开发框架seo是一种利用搜索引擎
  • 怎样建设网站空间网站开发中英文版如何写
  • 网站设计怎么收费注册安全工程师条件
  • 5. 逆矩阵
  • 济源专业网站建设(制作网站)网络技术学习网站
  • Redis过期策略与内存淘汰机制解析
  • Transformer(四)---解码器部分实现、输出部分实现及模型搭建
  • 网站开发毕业设计任务书注册推广赚钱一个30元
  • 邯郸网络广播电视台北京网站seo技术厂家
  • leetcode 695 岛屿的最大面积
  • LLaVA-NeXT-Interleave论文阅读
  • 邢台企业网站制作公司中建国际建设有限公司网站
  • 长春火车站防疫要求做网站都要用到框架吗
  • 集合进阶 - HashMap 篇
  • 从原图到线图再到反推:网络图几何与拓扑的结合分析
  • Lua下载和安装教程(附安装包)
  • JAVA实验课程第五次作业分析与代码示例
  • 龙口网站制作公司深圳知名设计公司有哪些
  • 网站数据修改网页界面设计的起源
  • 东莞建设网站官网住房和城乡wordpress 如何修改like和dislike
  • Gopher二次编码原因解析
  • 【ARM汇编语言基础】-数据处理指令(七)