美文网首页
Unreal Slate框架随笔

Unreal Slate框架随笔

作者: Mr_约科 | 来源:发表于2019-12-26 22:56 被阅读0次
小项 备注
时间 2019 年 12 月 26 日
修改时间 2020 年 3 月 22 日、2020年4月11日
城市 北京市房山区
天气
心情 凑合

UE4 的 编辑器都是建立在 Slate整个框架下,包括UE4 用于Runtime游戏的 UMG 这套这是基于Slate系统的。

Slate用户界面系统为开发者提供了 引擎源码 和 编辑器Editor 的直接访问权(开发者工具——Widget Reflecor)

0. Slate控件(S前缀的类)继承关系【SlateCore模块】

至于为什么是S开头的类,戳下面官方的链接:

https://docs.unrealengine.com/en-US/Programming/Introduction/index.html

继承关系.png

下面我们把注意力放在 FSlot类型上

(1)SCompoundWidget

SCompoundWidget 中含有一个Slot,意味着他可以添加一个 children widget

SCompoundWidget.png

(2)SLeafWidget

SLeafWidget 中没有Slot成员,也就是不含widget

SLeafWidget.png

(3)Spanel

Spanel 中可以含有多个 widget,这个没本身没有加 Slot 结构,但是 继承于他的继承类,会添加自己的 Slot结构,例如 Soverlay、SBoxPanel派生类

(3.1)Soverlay
SOverlay.png
(3.2)SBoxPanel
SBoxPanel.png
(3.2.1)SVerticalBox
SVerticalBox.png
(3.2.2)SHorizontalBox
SHorizontalBox.png

关于FSlot 的作用,在其基类中可以看出,它重载了操作符 [ ],所以我们可以 使用下面这种写法,其添加 childrenwidhet,而控件的父子关系是依托Slot实现的。Slate除了底层的渲染功能实现之外,定义了一套自己的语法,目的就是定义 UI 的层级结构和布局—也就是Slot。

ChildSlot
    [
        SNew(...)
    ]
TSlotBase.png

每一个 slot 可以存放一个widget,有的控件只有一个 slot,所以它只有一个孩子,有的控件有多个孩子,就有一个 slotArray对应,而他的排列就跟重写 SWidget基类的 OnArrangeChildren纯虚函数有关了。

多个Slot.png

1. 控件参数声明

(1)声明

Slate 声明式语法使得开发者可以直接构建用户界面,而不需要添加中间层进行处理。提供了一套 完整的宏 来简化声明及创建控件的过程。
宏 SLATE_BEGIN_ARGS宏 SLATE_END_ARGS 之间的声明参数。常用的参数类型有 SLATE_ATTRIBUTE(属性)、SLATE_EVENT(事件)、SLATE_ARGUMENT(参数)、SLATE_NAMED_SLOT(插槽) 和 SLATE_DEFAULT_SLOT

  • 例如:SLATE_ATTRIBUTE(属性)
    声明格式:SLATE_ATTRIBUTE(变量类型,变量名)*

  • 例如:SLATE_EVENT(事件)
    声明格式:SLATE_EVENT(变量类型,变量名)*
    注意:这里的变量类型为 UE4 的委托类型

  • 实例

DECLARE_DELEGATE_OneParam(FMyEvent, FString);

class EXSLATEWIDGET_API SMyCompoundWidget : public SCompoundWidget
{
public:
        SLATE_BEGIN_ARGS( SSubMenuButton )
            : _ShouldAppearHovered( false )
            {
 
            }
          
            SLATE_ATTRIBUTE( bool, ShouldAppearHovered )

            SLATE_ATTRIBUTE( FString, Label )
          
            SLATE_EVENT( FOnClicked, OnClicked )
         
            SLATE_NAMED_SLOT( FArguments, FSimpleSlot, Content )

            SLATE_EVENT(FMyEvent, MyEvent)       
        SLATE_END_ARGS()
};

(2)初始化

按上面用相应的宏声明之后,实际上参数名变为"_" + "宏里面的变量名",如上面 “ShouldAppearHovered ” 参数名为“_ShouldAppearHovered ”. SCompoundWidget的参数初始化和C++类差不多,如同下面:

SLATE_BEGIN_ARGS(SSubMenuButton )
{
    _ShouldAppearHovered = false ;
}

SLATE_BEGIN_ARGS(SSubMenuButton ):
        _ShouldAppearHovered ( false )
    {
 
    }

而在 上述的实例中采用了第二种初始化的方式。

2. 构建对象

通过 宏 声明的参数 与 类成员变量 之间的转移(参数 与 变量的区别)

在构建 Slate 对象的时候,传入的参数,并不是直接通过 上面我们通过宏去定义的那些参数去直接执行的,上面定义的那些参数 仅仅是为了 方便传递,所以还需要在 定义类的 成员变量(或委托变量)
上面实例中的类,重新定义为:

以 Label 这个声明参数为例,在类中增加了 这个声明参数 对应的 成员变量

DECLARE_DELEGATE_OneParam(FMyEvent, FString);

class EXSLATEWIDGET_API SMyCompoundWidget : public SCompoundWidget
{
public:
        SLATE_BEGIN_ARGS( SSubMenuButton )
            : _ShouldAppearHovered( false )
            {
 
            }
          
            SLATE_ATTRIBUTE( bool, ShouldAppearHovered )

            SLATE_ATTRIBUTE( FString, Label )
          
            SLATE_EVENT( FOnClicked, OnClicked )
         
            SLATE_NAMED_SLOT( FArguments, FSimpleSlot, Content )

            SLATE_EVENT(FMyEvent, MyEvent)       
        SLATE_END_ARGS()

public:
        void Construct(const FArguments& InArgs);

private:
        FString Label ;

};

/////////////////////////////////////////////////////////
void SMyCompoundWidget::Construct(const FArguments& InArgs)
{
         
        Label = InArgs._Label ;
        /*
        ChildSlot
        [
            // Populate the widget
        ];
        */

}

实际构建的代码写法

ContextualEditingWidget->AddSlot()
.Padding( 2.0f )
[
    SNew( SDetailSection )
    .SectionName("StaticMeshSection")
    .SectionTitle( LOCTEXT("StaticMeshSection", "Static Mesh").ToString() )
    .Content()
    [
        SNew( SVerticalBox )
        + SVerticalBox::Slot()
        .Padding( 3.0f, 1.0f )
        [
            SNew( SHorizontalBox )
            + SHorizontalBox::Slot()
            .Padding( 2.0f )
            [
                SNew( SComboButton )
                .ButtonContent()
                [
                    SNew( STextBlock )
                    .Text( LOCTEXT("BlockingVolumeMenu", "Create Blocking Volume") ) 
                    .Font( FontInfo )
                ]
                .MenuContent()
                [
                    BlockingVolumeBuilder.MakeWidget()
                ]
            ]
        ]

    ]
];

看 一下 的定义,就知道这些写法,以及 Construct 函数中 FArguments 参数是怎么回事了 :

宏的定义.png

这些写法 就是在对属性 赋值,并且这些声明的变量都会存在 FArguments 结构下面,
void Construct(const FArgument& InArgs);
在初始化函数可以使用到 SNew 时候传来的参数。

对于想了解 SNew 背后的逻辑的朋友,可以看下面的链接:

https://www.yuanmas.com/info/rxzKZA9ORe.html

(1)风格

在构建时,代码的具体写法中,你可以创建风格,并将其应用到一个 控件的各个部分上,这使得用户界面上迭代处理组件的外观、共享及重用风格变得更加容易。

在UE4中,主要的风格被定义在一下两个源文件中:

  • Engine \ Source \ Runtime \ SlateCore \ Public \ Styling \ CoreStyle.h
  • Engine \ Source \ Editor \ EditorStyle \ Private \ SlateEditorStyle.cpp
// Tool bar
{
    Set( "ToolBar.Background", FSlateBoxBrush( TEXT("Common/GroupBorder"), FMargin(4.0f/16.0f) ) );

    Set( "ToolBarButton.Normal", FSlateNoResource() );      // Note: Intentionally transparent background
    Set( "ToolBarButton.Pressed", FSlateBoxBrush( TEXT("Old/MenuItemButton_Pressed"), 4.0f/32.0f ) );
    Set( "ToolBarButton.Hovered", FSlateBoxBrush( TEXT("Old/MenuItemButton_Hovered"), 4.0f/32.0f ) );

    // Tool bar buttons are sometimes toggle buttons, so they need styles for "checked" state
    Set( "ToolBarButton.Checked", FSlateBoxBrush( TEXT("Old/MenuItemButton_Pressed"),  4.0f/32.0f, FLinearColor( 0.3f, 0.3f, 0.3f ) ) );
    Set( "ToolBarButton.Checked_Hovered", FSlateBoxBrush( TEXT("Old/MenuItemButton_Hovered"),  4.0f/32.0f ) );
    Set( "ToolBarButton.Checked_Pressed", FSlateBoxBrush( TEXT("Old/MenuItemButton_Pressed"),  4.0f/32.0f, FLinearColor( 0.5f, 0.5f, 0.5f ) ) );

    // Tool bar button label font
    Set( "ToolBarButton.LabelFont", FSlateFontInfo( TEXT("Roboto-Regular"), 8 ) );
}

构建的代码写法改为

SNew( SBorder )
.BorderImage( FEditorStyle::GetBrush( "ToolBar.Background" ) )
.Content()
[
    SNew(SHorizontalBox)

    // Compile button (faked to look like a multibox button)
    +SHorizontalBox::Slot()
    [
        SNew(SButton)
        .Style(TEXT("ToolBarButton"))
        .OnClicked( InKismet2.ToSharedRef(), &FKismet::Compile_OnClicked )
        .IsEnabled( InKismet2.ToSharedRef(), &FKismet::InEditingMode )
        .Content()
        [
            SNew(SVerticalBox)
            +SVerticalBox::Slot()
            .Padding( 1.0f )
            .HAlign(HAlign_Center)
            [
                SNew(SImage)
                .Image(this, &SBlueprintEditorToolbar::GetStatusImage)
                .ToolTipText(this, &SBlueprintEditorToolbar::GetStatusTooltip)
            ]
            +SVerticalBox::Slot()
            .Padding( 1.0f )
            .HAlign(HAlign_Center)
            [
                SNew(STextBlock)
                .Text(LOCTEXT("CompileButton", "Compile"))
                .Font( FEditorStyle::GetFontStyle( FName( "ToolBarButton.LabelFont" ) ) )
                .ToolTipText(LOCTEXT("CompileButton_Tooltip", "Recompile the blueprint"))
            ]
        ]
    ]
]

参考文章
https://docs.unrealengine.com/zh-CN/Programming/Slate/index.html
https://docs.unrealengine.com/zh-CN/Engine/UMG/index.html
https://blog.csdn.net/qq_29523119/article/details/98475938
https://blog.csdn.net/pizi0475/article/details/50471207
https://zhuanlan.zhihu.com/p/56127773

相关文章

  • Unreal Slate框架随笔

    小项备注时间2019 年 12 月 26 日修改时间2020 年 3 月 22 日、2020年4月11日城市北京市...

  • Slate Slate Slate

    卖手机的好友给了我台SONY的Xperia Z Ultra让我玩两天顺便写个评测帮他推销推销。不过,我真的才玩到第...

  • Slate Slate Slate (prologue)

    每个尺寸都有,各取所需。 小到3.5的Galaxy Young,大到6.3的Galaxy Mega,甚至...

  • 构建API服务器6

    文档 将slate集成到项目中 集成slate 配置构建文件app/docs/slate/config.rb 现在...

  • 电影《实习生》口语笔记17

    Clean slate Let’s clean-slate it. 让我们重新开始。 Slate石板,岩板的意思,...

  • slate api文档

    https://github.com/slatedocs/slate/wiki/Using-Slate-Nativ...

  • Lighting视频

    Lighting with Unreal Engine Masterclass | Unreal Dev Day ...

  • UE4 SlateUI系统初探

    问题列表: Slate是什么 整个编辑器都是用Slate做得吗 场景的绘制工作是如何与Slate结合的? Slat...

  • 部署 Slate

    原文:Deploying Slate Slate 会生成一系列静态的 HTML,JavaScript 和 CSS ...

  • Slate——为 API 生成精美的静态文档

    原文:slate - README Slate 可以帮助你创建美观、智能、响应迅速的 API 文档。 以上 API...

网友评论

      本文标题:Unreal Slate框架随笔

      本文链接:https://www.haomeiwen.com/subject/rifroctx.html