unreal 自定义 Slate Style Sets
一、创建 xxStyle 类
首先,我们创建一个名为 TestStyles 的类,用于自定义 Slate Style Sets。这里没有使用 Unreal Editor 的创建向导,你也可以选择使用向导来创建。
1. TestStyles.h 文件内容
#pragma once
#include "SlateStyle.h"
class TestStyles
{
public:
static void Initialize();
static void Shutdown();
static const class ISlateStyle& Get();
static FName GetStyleSetName();
private:
static TSharedRef<class FSlateStyleSet> Create();
static TSharedPtr<class FSlateStyleSet> Instance;
};
2. TestStyles.cpp 文件内容
#include "Test05.h"
#include "TestStyles.h"
#include "SlateGameResources.h"
TSharedPtr<FSlateStyleSet> TestStyles::Instance = nullptr;
void TestStyles::Initialize()
{
if (!Instance.IsValid())
{
Instance = Create();
FSlateStyleRegistry::RegisterSlateStyle(*Instance);
}
}
void TestStyles::Shutdown()
{
FSlateStyleRegistry::UnRegisterSlateStyle(*Instance);
ensure(Instance.IsUnique());
Instance.Reset();
}
const class ISlateStyle& TestStyles::Get()
{
return *Instance;
}
FName TestStyles::GetStyleSetName()
{
static FName StyleSetName(TEXT("TestStyles"));
return StyleSetName;
}
TSharedRef<class FSlateStyleSet> TestStyles::Create()
{
return FSlateGameResources::New(TestStyles::GetStyleSetName(), "/game/ui", "/game/ui");
}
3. 资源路径注意事项
这里需要特别注意 FSlateGameResources 资源路径的相对位置。在 Unreal 中,/game 代替了 /context,存放在 /context 目录下的资源,在地址路径中要统一更名为 /game。这个路径非常重要,当遇到错误时,一定要检查该路径,看是否能找到 style 资源。
4. 初始化位置选择
在本文中,没有按照网页中作者的方式创建 GameModule,而是将 TestStyles 的初始化放在了自定义的 GameMode 中。实际上,只要能合理地让 TestStyles 初始化,放在哪里都可以,但可能需要考虑创建的时序性,目前暂不考虑这个问题。
AMyGameMode::AMyGameMode()
{
this->HUDClass = AMyHUD::StaticClass();
FSlateStyleRegistry::UnRegisterSlateStyle(TestStyles::GetStyleSetName()); // 参考网页的作者,只为防重复注册
TestStyles::Initialize();
}
二、创建由 Unreal Editor 向导生成的类
1. 操作步骤
在 Class 目录下创建 New Class,生成以下代码。
2. GlobalTestWidgetStyle.h 文件内容
#pragma once
#include "Styling/SlateWidgetStyle.h"
#include "SlateWidgetStyleContainerBase.h"
#include "GlobalTestWidgetStyle.generated.h"
/*
*
*/
USTRUCT()
struct TEST05_API FGlobalTestStyle : public FSlateWidgetStyle
{
GENERATED_USTRUCT_BODY()
public:
FGlobalTestStyle();
virtual ~FGlobalTestStyle();
// FSlateWidgetStyle
virtual void GetResources(TArray<const FSlateBrush*>& OutBrushes) const override;
static const FName TypeName;
virtual const FName GetTypeName() const override { return TypeName; }
static const FGlobalTestStyle& GetDefault();
UPROPERTY(EditAnywhere, Category = Appearance)
FTextBlockStyle textBlockStyle;
};
UCLASS(hidecategories = Object, MinimalAPI)
class UGlobalTestWidgetStyle : public USlateWidgetStyleContainerBase
{
GENERATED_BODY()
public:
/*
* The actual data describing the widget appearance.
*/
UPROPERTY(Category = Appearance, EditAnywhere, meta = (ShowOnlyInnerProperties))
FGlobalTestStyle WidgetStyle;
virtual const struct FSlateWidgetStyle* const GetStyle() const override
{
return static_cast<const struct FSlateWidgetStyle*>(&WidgetStyle);
}
};
3. GlobalTestWidgetStyle.cpp 文件内容
#include "Test05.h"
#include "GlobalTestWidgetStyle.h"
FGlobalTestStyle::FGlobalTestStyle()
{
}
FGlobalTestStyle::~FGlobalTestStyle()
{
}
const FName FGlobalTestStyle::TypeName(TEXT("FGlobalTestStyle"));
const FGlobalTestStyle& FGlobalTestStyle::GetDefault()
{
static FGlobalTestStyle Default;
return Default;
}
void FGlobalTestStyle::GetResources(TArray<const FSlateBrush*>& OutBrushes) const
{
}
三、创建和修改资源
1. 创建资源
在 Content 目录中创建 Style,地址要与之前 FSlateGameResources::New 中使用的地址一致,目前使用的是 /Game/ui 位置的地址,实际上该位置应替换为 /content/ui。创建后会得到一个资源,这个资源的名字很重要,后续需要对应上。
2. 修改资源内容
双击该资源修改里面的内容,由于自定义的 FSlateWidgetStyle 中定义了 FTextBlockStyle textBlockStyle,所以可以在这里修改字体和字体大小等属性。
UPROPERTY(EditAnywhere, Category = Appearance)
FTextBlockStyle textBlockStyle;
四、实例化显示
最后一步是实例化显示,以下是测试代码片段,写在 AMyHUD::BeginPlay 函数中。
void AMyHUD::BeginPlay()
{
// 注意,这里的 "TestButtonStyle01" 是资源的名字
auto ss = TestStyles::Get().GetWidgetStyle<FGlobalTestStyle>("TestButtonStyle01");
textBlock = SNew(STextBlock)
.TextStyle(&ss.textBlockStyle)
.Text(FText::FromString("Hello World !"));
GEngine->GameViewport->AddViewportWidgetContent(SNew(SWeakWidget).PossiblyNullContent(textBlock.ToSharedRef()));
}
完成以上所有步骤后,就可以看到显示效果了。