UE4C++Slate与C++DPI(屏幕自适应方式)设定

本文介绍了如何在UE4中使用C++和Slate创建自适应DPI的UI,通过设置DPIScaling并在C++代码中实现自定义的缩放规则。首先讲解了UE4中DPIScaling的基本原理和设置方法,然后展示了创建自定义HUD并绑定DPI缩放函数的过程,最后展示了如何在HUD中添加SlateWidget并应用DPI规则,确保UI元素随屏幕尺寸变化而适配。
摘要由CSDN通过智能技术生成

UE4C++Slate与C++DPI(屏幕自适应方式)设定

DPI原理
我们常常以在ProjectSetting->UserInterface->DPI Scaling的方式设置DPI,让物体基于一个边进行缩放
在这里插入图片描述
如图,图中以最短边为基础轴进行缩放,并设置俩个基点(540,0.5)与(1080,1),其窗口短边变化时候,从540 - 1080变化时,窗口内容按照0.5 - 1之间的缩放比例进行变化,而最短边大于1080或者小于540的时候,屏幕窗口内容都不会发生缩放变化,其中还有其他几种缩放形式,有兴趣的稍微懂点英文大概就知道什么意思了,再这也不过多赘述。
再次之前,我们将DPI设置成一条直线,便于看出我们代码中所自定义的DPI形式,如下图所示:
在这里插入图片描述
c++中创建我们自己的HUD
在这里插入图片描述
WorldSetting中设置我们的HUD
在这里插入图片描述
也许有些小伙伴在界面中找不到WorldSetting,打开方式见下图:
在这里插入图片描述
创建Slate Widget类型,用作HUD的中的内容显示
在这里插入图片描述
再次之前建议可以看看Slate的一些基础描述

  • .h文件
// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.h"
#include "GameSand_Style.h"


/**
 * 
 */
class GAME_SANDBOX_API SGameSand_HUD_Widget : public SCompoundWidget
{
public:
	SLATE_BEGIN_ARGS(SGameSand_HUD_Widget)
	{}
	SLATE_END_ARGS()

	/** Constructs this widget with InArgs */
		void Construct(const FArguments& InArgs);
private:
	//用于绑定UIScaler的缩放系数
	float GetUIScaler()const;
	//获取屏幕尺寸
	FVector2D GetViewportSize()const;

private:
	//获取蓝图中的Menu样式,用作图片的资源样式设置
	const struct FGameSand_MenuStyle* MenuStyle;
	//DPI缩放系数
	TAttribute<float>UIScaler;
};
  • .cpp文件
// Fill out your copyright notice in the Description page of Project Settings.


#include "UI/SGameSand_HUD_Widget.h"
#include "SlateOptMacros.h"
#include "Widgets/Images/SImage.h"
#include "UI/GameSand_MenuWidgetStyle.h"
#include "UI/GameSand_Style.h"
#include "UI/GameSand_MenuWidgetStyle.h"
#include "Widgets/Layout/SDPIScaler.h"



BEGIN_SLATE_FUNCTION_BUILD_OPTIMIZATION
void SGameSand_HUD_Widget::Construct(const FArguments& InArgs)
{
	//获取编辑器中的MenuStyle,这个获取方式只是封装了通过路径获取蓝图中的WidgetStyle
	MenuStyle = &GameSand_Style::Get().GetWidgetStyle<FGameSand_MenuStyle>("BP_GameSand_Style");
	//绑定缩放规则函数
	UIScaler.Bind(this, &SGameSand_HUD_Widget::GetUIScaler);
	ChildSlot
		[
			//创建DPI绑定其缩放规则,在下面的子类都根据这个规则进行缩放
			SNew(SDPIScaler)
			.DPIScale(UIScaler)
		[
			//创建Overlay,添加插槽
			SNew(SOverlay)
			+ SOverlay::Slot()
		//设置其子类的布局方式,这里设置成FILL
		.HAlign(HAlign_Fill)
		.VAlign(VAlign_Fill)
		//设置子类Padding
		.Padding(FMargin(30.f))
		[
			//设置图片,并设置其笔刷
			SNew(SImage)
			//这里的MenuHUDBackgroundBrush是创建的笔刷,可以自己删除,这里是用作演示
			.Image(&MenuStyle->MenuHUDBackgroundBrush)
		]
	+ SOverlay::Slot()
		.HAlign(HAlign_Center)
		.VAlign(VAlign_Center)
		[
			SNew(SImage)
			//这里的MenuBackgroundBrush是创建的笔刷,可以自己删除,这里是用作演示
			.Image(&MenuStyle->MenuBackgroundBrush)
		]
		]
		];
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION

float SGameSand_HUD_Widget::GetUIScaler() const
{
	//DPI : Resolutuon 1080 ScaleY/1080.f
	return GetViewportSize().Y / 1080.f;
}

FVector2D SGameSand_HUD_Widget::GetViewportSize() const
{
	FVector2D Result(1920, 1080);
 	if (GEngine && GEngine->GameViewport)
 	//获取显示窗口大小,返回给Result
 		GEngine->GameViewport->GetViewportSize(Result);
	return Result;
}

HUD中创建我们的Widget

// Fill out your copyright notice in the Description page of Project Settings.

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/HUD.h"
#include "Templates/SharedPointer.h"
#include "GameSand_HUD.generated.h"

/**
 * 
 */
UCLASS()
class GAME_SANDBOX_API AGameSand_HUD : public AHUD
{ 
	GENERATED_BODY()

public:
	AGameSand_HUD();
	TSharedPtr<class SGameSand_HUD_Widget>GameSand_HUD_Widget;
};
// Fill out your copyright notice in the Description page of Project Settings.


#include "GamePlay/GameSand_HUD.h"
#include "UI/SGameSand_HUD_Widget.h"

AGameSand_HUD::AGameSand_HUD()
{  
	if (GEngine&&GEngine->GameViewport)
	{
		GameSand_HUD_Widget=SAssignNew(GameSand_HUD_Widget, SGameSand_HUD_Widget);
		GEngine->GameViewport->AddViewportWidgetContent(GameSand_HUD_Widget.ToSharedRef());
	}
}

在蓝图中找到自己创建的WidgetStyle,设置其图片等系列东西
在这里插入图片描述
通过短轴的拉伸,我们可以看到图片的DPI确实发生了变化
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值