四、菜单布局实现
通过点击按钮改变图片布局
SlAiMenuHUDWidget.h
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include"SOverlay.h"
/**
*
*/
class SLAICOURSE_API SSlAiMenuHUDWidget : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SSlAiMenuHUDWidget)
{
}
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
private:
//绑定UIScaler
float GetUIScaler() const;
//获取屏幕尺寸
FVector2D GetViewportSize() const;
FReply OnClick();
private:
//获取Menu样式
const struct FSlAiMenuStyle* MenuStyle;
//DPI缩放系数
TAttribute<float> UIScaler;
//获取SOverlay---Image的Slot
SOverlay::FOverlaySlot* ImageSlot;
};
SlAiMenuHUDWidget.cpp
#include "SSlAiMenuHUDWidget.h"
#include "SlateOptMacros.h"
#include"SButton.h"
#include"SImage.h"
#include "SlAiStyle.h"
#include "SlAiMenuWidgetStyle.h"
#include"Engine/Engine.h"
#include"SDPIScaler.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiMenuHUDWidget::Construct(const FArguments& InArgs)
{
//获取编辑器的MenuStyle
//BPSlAiMenuStyle 要获取的资源名称
//MenuStyle 将引用Game/UI/Style/BPSlAiMenuStyle
MenuStyle = &SlAiStyle::Get().GetWidgetStyle<FSlAiMenuStyle>("BPSlAiMenuStyle");
//绑定缩放规则方法
UIScaler.Bind(this, &SSlAiMenuHUDWidget::GetUIScaler);
ChildSlot
[
SNew(SDPIScaler)
.DPIScale(UIScaler)
[
SNew(SOverlay)
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SImage)
.Image(&MenuStyle->MenuHUDBackgroundBrush)
]
+ SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
//ImageSlot获取SOverlay的插槽
.Expose(ImageSlot)
[
SNew(SImage)
.Image(&MenuStyle->MenuBackgroundBrush)
]
+SOverlay::Slot()
.HAlign(HAlign_Left)
.VAlign(VAlign_Top)
[
SNew(SButton)
//绑定点击事件
.OnClicked(this,&SSlAiMenuHUDWidget::OnClick)
]
]
];
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
float SSlAiMenuHUDWidget::GetUIScaler() const
{
return GetViewportSize().Y / 1080.f;
}
FVector2D SSlAiMenuHUDWidget::GetViewportSize() const
{
FVector2D Result(1920, 1080);
if (GEngine && GEngine->GameViewport)
GEngine->GameViewport->GetViewportSize(Result);
return Result;
}
//通过调整Overlay插槽位置改变其插槽内容的位置
FReply SSlAiMenuHUDWidget::OnClick()
{
//将ImageSlot调整为(Right,Bottom)
ImageSlot->HAlign(HAlign_Right)
.VAlign(VAlign_Bottom);
//让系统知道OnClick()已经完成了
return FReply::Handled();
}
在SlAiStyle中获取MenuStyle
SlAiStyle.h
#pragma once
#include "CoreMinimal.h"
#include"SlateBasics.h"
/**
*
*/
//模仿单例模式
class SLAICOURSE_API SlAiStyle
{
public:
...
//获取Menu样式
static const struct FSlAiMenuStyle* GetMenuStyle();
private:
...
};
SlAiStyle.cpp
...
const FSlAiMenuStyle* SlAiStyle::GetMenuStyle()
{
const struct FSlAiMenuStyle* MenuStyle;
MenuStyle = &SlAiStyle::Get().GetWidgetStyle<FSlAiMenuStyle>("BPSlAiMenuStyle");
return MenuStyle;
}
菜单布局
SlAiMenuWidgetStyle.h
...
/*
* Menu左图标的Brush
*/
UPROPERTY(EditAnywhere, Category = Menu)
FSlateBrush LeftIconBrush;
/*
* Menu右图标的Brush
*/
UPROPERTY(EditAnywhere, Category = Menu)
FSlateBrush RightIconBrush;
/*
* Menu标题Border的Brush
*/
UPROPERTY(EditAnywhere, Category = Menu)
FSlateBrush TitleBorderBrush;
...
SlAiMenuHUDWidget.h
...
private:
...
//菜单指针
TSharedPtr<class SSlAiMenuWidget> MenuWidget;
};
SlAiMenuHUDWidget.cpp
...
#include "SSlAiMenuWidget.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiMenuHUDWidget::Construct(const FArguments& InArgs)
{
//获取编辑器的MenuStyle
MenuStyle = &SlAiStyle::Get().GetWidgetStyle<FSlAiMenuStyle>("BPSlAiMenuStyle");
//绑定缩放规则方法
UIScaler.Bind(this, &SSlAiMenuHUDWidget::GetUIScaler);
ChildSlot
[
SNew(SDPIScaler)
.DPIScale(UIScaler)
[
SNew(SOverlay)
+ SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
[
SNew(SImage)
.Image(&MenuStyle->MenuHUDBackgroundBrush)
]
//将菜单控件插入HUDWidget
+ SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SAssignNew(MenuWidget,SSlAiMenuWidget)
]
]
];
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
SlAiMenuWidget.h
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
/**
*
*/
class SLAICOURSE_API SSlAiMenuWidget : public SCompoundWidget
{
public:
SLATE_BEGIN_ARGS(SSlAiMenuWidget)
{
}
SLATE_END_ARGS()
/** Constructs this widget with InArgs */
void Construct(const FArguments& InArgs);
private:
//保存根节点
TSharedPtr<class SBox> RootSizeBox;
//保存标题
TSharedPtr<class STextBlock> TitleText;
};
SlAiMenuWidget.cpp
#include "SSlAiMenuWidget.h"
#include "SlateOptMacros.h"
#include"SlAiStyle.h"
#include "SlAiMenuWidgetStyle.h"
#include"SBox.h"
#include"SImage.h"
#include"SBorder.h"
#include"STextBlock.h"
BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SSlAiMenuWidget::Construct(const FArguments& InArgs)
{
//MenuStyle = &SlAiStyle::Get().GetWidgetStyle<FSlAiMenuStyle>("BPSlAiMenuStyle");
ChildSlot
[
//菜单背景图片
SAssignNew(RootSizeBox,SBox)
[
SNew(SOverlay)
+SOverlay::Slot()
.HAlign(HAlign_Fill)
.VAlign(VAlign_Fill)
.Padding(FMargin(0.f,50.f,0.f,0.f))
[
SNew(SImage)
//通过单例类获取编辑器的MenuStyle
.Image(&SlAiStyle::GetMenuStyle()->MenuBackgroundBrush)
]
//菜单左侧图标
+SOverlay::Slot()
.HAlign(HAlign_Left)
.VAlign(VAlign_Center)
.Padding(FMargin(0.f,25.f,0.f,0.f))
[
SNew(SImage)
.Image(&SlAiStyle::GetMenuStyle()->LeftIconBrush)
]
//菜单右侧图标
+ SOverlay::Slot()
.HAlign(HAlign_Right)
.VAlign(VAlign_Center)
.Padding(FMargin(0.f, 25.f, 0.f, 0.f))
[
SNew(SImage)
.Image(&SlAiStyle::GetMenuStyle()->RightIconBrush)
]
//菜单标题
+ SOverlay::Slot()
.HAlign(HAlign_Center)
.VAlign(VAlign_Top)
[
SNew(SBox)
.WidthOverride(400.f)
.HeightOverride(100.f)
[
SNew(SBorder)
.BorderImage(&SlAiStyle::GetMenuStyle()->TitleBorderBrush)
.HAlign(HAlign_Center)
.VAlign(VAlign_Center)
[
SAssignNew(TitleText, STextBlock)
.Font(SlAiStyle::Get().GetFontStyle("MenuItemStyle"))
.Text(FText::FromString("I am haha"))
]
]
]
]
];
//设置RootBox的大小
RootSizeBox->SetWidthOverride(600.f);
RootSizeBox->SetHeightOverride(510.f);
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
注意:
//声明
public:
//获取Menu样式
static const struct FSlAiMenuStyle* GetMenuStyle();
//定义
const FSlAiMenuStyle* SlAiStyle::GetMenuStyle()
{
const struct FSlAiMenuStyle* MenuStyle;
MenuStyle = &SlAiStyle::Get().GetWidgetStyle<FSlAiMenuStyle>("BPSlAiMenuStyle");
return MenuStyle;
}
//使用
SNew(SImage)
.Image(&SlAiStyle::GetMenuStyle()->LeftIconBrush)
//获取Menu样式
const struct FSlAiMenuStyle* MenuStyle;
MenuStyle = &SlAiStyle::Get().GetWidgetStyle<FSlAiMenuStyle>("BPSlAiMenuStyle");