原创文章,转载请注明出处。

点击观看上一篇《UE4 Slate四 SlateUI如何做UI动画》
点击观看下一篇《UE4 Slate六 SlateUI在Runtime结合我们的GamePlay使用》

1>前言

我们发现在Slate链式编程里面设置图片,设置字体,设置声音等很麻烦,因为要去构造这个图片字体声音等数据。
那么有没有更通用的方式让我们在编辑器里面通过资源去选择,然后读取它给我们的Slate使用呢?
答案是有的:也就是我们要介绍的FSlateWidgetStyle

2>自定义样式

我们会用到FSlateWidgetStyle类,自己继承一下,实现里面的方法,定义我们需要的图片,字体,声音等素材;然后去编辑器里面创建一个这样的资源类出来,中间我们要借助USlateWidgetStyleContainerBase类。
下面的USlateMainWidgetStyle 就是我们在编辑器里面创建的资源类。

2.1>定义我们的SlateMainWidgetStyle.h头文件

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

#pragma once

#include "CoreMinimal.h"
#include "Styling/SlateWidgetStyleContainerBase.h"
#include "Styling/SlateWidgetStyle.h"
#include "Styling/SlateBrush.h"
#include "Fonts/SlateFontInfo.h"
#include "Sound/SlateSound.h"
#include "Math/Color.h"
#include "SlateMainWidgetStyle.generated.h"

/**
 * 定制我们的Style类, 这样写Slate的时候我们就方便很多, 在UE4编辑器中设置好想要设置的Slate资源(比如图片、音频、Font等)
 */
USTRUCT()
struct FMainWidgetStyle : public FSlateWidgetStyle
{
	GENERATED_USTRUCT_BODY()

	//必须要这么写, 方法是要进行模板匹配函数的
	virtual void GetResources(TArray<const FSlateBrush*> & OutBrushes) const;
	virtual const FName GetTypeName() const;
	static const FMainWidgetStyle &GetDefault();
	static const FName TypeName;

	//Slate演示图片, 你想将slate上设置的图片
	UPROPERTY(EditAnywhere,Category = "Task")
	FSlateBrush TemplateImage;

	//你想将slate上设置的字体
	UPROPERTY(EditAnywhere, Category = "Task")
	FSlateFontInfo TemplateFont;

	//你想将slate上设置的声音
	UPROPERTY(EditAnywhere, Category = "Task")
	FSlateSound TemplateSound;

	//你想将slate上设置的颜色
	UPROPERTY(EditAnywhere, Category = "Task")
	FLinearColor TemplateColor;
};


//提供给编辑器内->右键资源浏览器->选择User Interface(就是创建UMG那一栏)->选择Slate Widget Style->再去选SlateMainWidgetStyle(我们的类名去掉U)
UCLASS()
class USlateMainWidgetStyle : public USlateWidgetStyleContainerBase
{
	GENERATED_BODY()

public:
	UPROPERTY(EditAnywhere, Category = "MyWidgetStyle", meta = (ShowOnlyInnerProperties))
	FMainWidgetStyle MyWidgetStyle;
	
	virtual const struct FSlateWidgetStyle* const GetStyle() const override
	{
		return static_cast<const struct FSlateWidgetStyle*>(&MyWidgetStyle);
	}
};

2.2>实现我们的SlateMainWidgetStyle.cpp实现文件

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

#include "SlateMainWidgetStyle.h"

const FName FMainWidgetStyle::TypeName(TEXT("MainWidgetStyle"));

void FMainWidgetStyle::GetResources(TArray<const FSlateBrush*> & OutBrushes) const
{

}

const FName FMainWidgetStyle::GetTypeName() const
{
	return TypeName;
}

const FMainWidgetStyle & FMainWidgetStyle::GetDefault()
{
	//C++11 magic staic
	static FMainWidgetStyle MyWidgetStyle;
	return MyWidgetStyle;
}


类定义好了,那么下一步去哪里加载呢

2.3>基于我们创建的USlateMainWidgetStyle 类在编辑器创建我们的SlateStyle资源,看下图即可

记住要选择SlateMainWidgetStyle
在这里插入图片描述

2.4> 资源创建好了,去哪里加载呢?

上面我们在/Game/Blogs_Slate/UI/SlateStyle目录里面创建了一个叫MyCustomWidgetStyleBP的Style资源类,
我们去哪里加载它?

2.4.1>加载我们的Style样式资源

2.4.1.1>指定加载目录 打开插件的test5_EditorStandlonWindowStyle.cpp

这个打开的文件名称为(你的插件叫什么名字+WindowStyle.cpp)
将下面的代码替换

TSharedRef< FSlateStyleSet > Ftest5_EditorStandlonWindowStyle::Create()
{
	TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("test5_EditorStandlonWindowStyle"));
	Style->SetContentRoot(IPluginManager::Get().FindPlugin("test5_EditorStandlonWindow")->GetBaseDir() / TEXT("Resources"));
	Style->Set("test5_EditorStandlonWindow.OpenPluginWindow", new IMAGE_BRUSH(TEXT("ButtonIcon_40x"), Icon40x40));
}

替换成下面的

TSharedRef< FSlateStyleSet > Ftest5_EditorStandlonWindowStyle::Create()
{
	TSharedRef< FSlateStyleSet > Style = FSlateGameResources::New(Ftest5_EditorStandlonWindowStyle::GetStyleSetName(), "/Game/Blogs_Slate/UI/SlateStyle", "/Game/Blogs_Slate/UI/SlateStyle");
	FString IconString = IPluginManager::Get().FindPlugin("test5_EditorStandlonWindow")->GetBaseDir() / TEXT("Resources/ButtonIcon_40x.png");
	Style->Set("test5_EditorStandlonWindow.OpenPluginWindow", new FSlateImageBrush(IconString, Icon40x40));

	return Style;
}

可以看到我们将RootContent目录强制指定成了我们项目Content/Blogs_Slate/UI/SlateStyle/目录,
并且我们将编辑器里面的插件图片目录也修改了一下,保证它能有图片。里面的目录都是可以拼接的,
其实里面的斜杠 / 符号就是一个操作符的重载,路径拼接作用。
AS

2.4.1.2>加载它

在我们的SMainSlate.h中定义一个我们的Style样式变量

//自定义的样式
const struct FMainWidgetStyle *MyCustomWidgetStyle;

在我们的SMainSlate.cpp的Construct()中去实例化它,MyCustomWidgetStyleBP就是我们的资源名,
因为在上一步我们已经指定过目录了。
我们创建了一张图片,然后用编辑器中指定好的图片和颜色应用到我们的SImage上。

这块可以去查引擎的代码是怎么写的,有很多例子。我测试不能直接将全路径写在这,包括引擎里面也没有这么用的。
都是先指定路径,然后这里是资源名称。引擎还有些是资源名称+里面的变量,这样的用法,大家也可以去查看。

void SMainSlate::Construct(const FArguments& InArgs)
{
	//获取自定义样式
	MyCustomWidgetStyle = &Ftest5_EditorStandlonWindowStyle::Get().GetWidgetStyle<FMainWidgetStyle>(TEXT("MyCustomWidgetStyleBP"));
	
	//链式编程 维护很麻烦...
	ChildSlot
	[
		SAssignNew(CanvasPanel_0, SConstraintCanvas)

		+ SConstraintCanvas::Slot()
		.Anchors(0.f)	//对应UMG这个文本控件上的Anchors属性,拷贝过来即可
		.Offset(FMargin(600, 0.f, 100, 100))	//这个可能会迷惑, 第一个参数在这是PositionX, 第二个参数在这是PositionY, 第三个参数在这是SizeX, 第四个参数在这是SizeY.找不到设置坐标的同学注意看这里
		.Alignment(FVector2D(0.f, 0.f))	//同样的, 对应Alignment是个FVector2D
		.AutoSize(false)			//对应AutoSize
		.ZOrder(0)
		[
			SNew(SImage)
			.Image(&MyCustomWidgetStyle->TemplateImage)	//加载我们Slate里面的图片(编辑器里面指定的)
			.ColorAndOpacity(FSlateColor(MyCustomWidgetStyle->TemplateColor))	//将我们Slate里面的颜色(编辑器里面指定的)给到这个图片
		]

2.5> 效果图

我们创建了一张图片,然后用编辑器中指定好的图片和颜色应用到我们的SImage上。
图片是可以直接显示的,但是颜色等部分属性没有及时更新的需要我们关闭界面再打开一次就能看到效果了。
在这里插入图片描述

点击观看上一篇《UE4 Slate四 SlateUI如何做UI动画》
点击观看下一篇《UE4 Slate六 SlateUI在Runtime结合我们的GamePlay使用》

谢谢,创作不易,大侠请留步… 动起可爱的双手,来个赞再走呗 <( ̄︶ ̄)>

Logo

这里是一个专注于游戏开发的社区,我们致力于为广大游戏爱好者提供一个良好的学习和交流平台。我们的专区包含了各大流行引擎的技术博文,涵盖了从入门到进阶的各个阶段,无论你是初学者还是资深开发者,都能在这里找到适合自己的内容。除此之外,我们还会不定期举办游戏开发相关的活动,让大家更好地交流互动。加入我们,一起探索游戏开发的奥秘吧!

更多推荐