四、菜单布局实现

通过点击按钮改变图片布局

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");

おすすめ

転載: blog.csdn.net/m0_51032168/article/details/121452697