unreal 自定义 Slate Style Sets

搜集到的最有价值的一篇教学,按照作者的方法尝试中遇到了一些问题。【感谢这位作者!

网址:https://wiki.unrealengine.com/Slate_Style_Sets_Part_2

在此,我将详述我的制作过程。本文原创,转载请写明出处,违者必究!

首先创建 xxStyle, 我这里测试就以 Test命名。

 1 #pragma once
 2 #include "SlateStyle.h"
 3 
 4 class TestStyles
 5 {
 6 public:
 7     static void Initialize();
 8 
 9     static void Shutdown();
10     
11     static const class ISlateStyle& Get();
12 
13     static FName    GetStyleSetName();
14 
15 private:
16 
17     static TSharedRef<class FSlateStyleSet>    Create();
18 
19     static TSharedPtr<class FSlateStyleSet>    Instance;
20 };

这个类是自己创建的,没有经过 UnrealEditor 的创建向导。(当然你也可以使用向导)

 1 #include "Test05.h"
 2 #include "TestStyles.h"
 3 #include "SlateGameResources.h"
 4 
 5 
 6 TSharedPtr<FSlateStyleSet> TestStyles::Instance = nullptr;
 7 
 8 
 9 void TestStyles::Initialize()
10 {
11     if (!Instance.IsValid())
12     {
13         Instance = Create();
14 
15         FSlateStyleRegistry::RegisterSlateStyle(*Instance);
16     }
17 }
18 
19 void TestStyles::Shutdown()
20 {
21     FSlateStyleRegistry::UnRegisterSlateStyle(*Instance);
22     ensure(Instance.IsUnique());
23     Instance.Reset();
24 }
25 
26 const class ISlateStyle& TestStyles::Get()
27 {
28     return *Instance;
29 }
30 
31 FName TestStyles::GetStyleSetName()
32 {
33     static FName StyleSetName(TEXT("TestStyles"));
34     return StyleSetName;
35 }
36 
37 TSharedRef<class FSlateStyleSet> TestStyles::Create()
38 {
39     return FSlateGameResources::New(TestStyles::GetStyleSetName(), "/game/ui", "/game/ui");
40 }

这里需要注意:FSlateGameResources 资源路径的相对位置。 /game 代替了 /context, 存放在 /context 目录下的资源,统一在地址路径中更名为 /game。

这个路径很重要!遇到错误的时候,一定要回来看看这个路径,看看能否找到 style 资源。

在这里,我没有按照网页中作者的方式创建 GameModule。(事实上我尝试了,但我失败了,暂时不想在此花费时间,所以改路。我放在了自定义的GameMode中)。

我认为只要能合理化的让 TestStyles 初始化,放哪都不是问题,(当然或许需要考虑创建的时序性,但目前我还没此顾虑)。

1 AMyGameMode::AMyGameMode()
2 {       
3    this->HUDClass = AMyHUD::StaticClass();      
4    FSlateStyleRegistry::UnRegisterSlateStyle(TestStyles::GetStyleSetName());// 参考网页的作者。只为防重复注册。       
5    TestStyles::Initialize();
6 }

下面这个类,是由 UnrealEditor 向导生成的,操作如下:

在 Class 目录下创建 New Class。 

 1 #pragma once
 2 
 3 
 4 #include "Styling/SlateWidgetStyle.h"
 5 #include "SlateWidgetStyleContainerBase.h"
 6 
 7 #include "GlobalTestWidgetStyle.generated.h"
 8 
 9 /**
10  * 
11  */
12 USTRUCT()
13 struct TEST05_API FGlobalTestStyle : public FSlateWidgetStyle
14 {
15     GENERATED_USTRUCT_BODY()
16 public:
17 
18     FGlobalTestStyle();
19     virtual ~FGlobalTestStyle();
20 
21     // FSlateWidgetStyle
22     virtual void GetResources(TArray<const FSlateBrush*>& OutBrushes) const override;
23     static const FName TypeName;
24     virtual const FName GetTypeName() const override { return TypeName; };
25     static const FGlobalTestStyle& GetDefault();
26 
27     UPROPERTY(EditAnywhere, Category = Appearance)
28     FTextBlockStyle textBlockStyle;
29 };
30 
31 /**
32  */
33 UCLASS(hidecategories=Object, MinimalAPI)
34 class UGlobalTestWidgetStyle : public USlateWidgetStyleContainerBase
35 {
36     GENERATED_BODY()
37 
38 public:
39     /** The actual data describing the widget appearance. */
40     UPROPERTY(Category=Appearance, EditAnywhere, meta=(ShowOnlyInnerProperties))
41     FGlobalTestStyle WidgetStyle;
42 
43     virtual const struct FSlateWidgetStyle* const GetStyle() const override
44     {
45         return static_cast< const struct FSlateWidgetStyle* >( &WidgetStyle );
46     }
47 };
 1 #include "Test05.h"
 2 #include "GlobalTestWidgetStyle.h"
 3 
 4 
 5 FGlobalTestStyle::FGlobalTestStyle()
 6 {
 7 
 8 }
 9 
10 FGlobalTestStyle::~FGlobalTestStyle()
11 {
12 }
13 
14 const FName FGlobalTestStyle::TypeName(TEXT("FGlobalTestStyle"));
15 
16 const FGlobalTestStyle& FGlobalTestStyle::GetDefault()
17 {
18     static FGlobalTestStyle Default;
19     return Default;
20 }
21 
22 void FGlobalTestStyle::GetResources(TArray<const FSlateBrush*>& OutBrushes) const
23 {
24 
25 }

  

这里是重点, 我自己在作者的网页中没有看懂,最终咨询了同事后试验才找到正路。

在 Content 目录中创建 Style. 这个地址一定要是之前提到的 FSlateGameResources::New(  中使用的 地址,目前我用的是 /Game/ui 位置的地址,(参照上文解释)/Game/ui 的位置应该被替换成 /content/ui,如图:

在此创建:

得到一个 资源,这个名字也很重要,之后要对应上。

现在就双击修改里面的内容。

这个东西会存在,就是因为自定义的 FSlateWidgetStyle 中定义了 

1  UPROPERTY(EditAnywhere, Category = Appearance)
2 
3  FTextBlockStyle textBlockStyle; 

这正是它。

我修改了字体和字体大小。

到了最后一步,实例化显示了,测试代码片段如下,我写在 

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()));            
}

所有步骤都做完了。可以显示了。效果如图:

原文中提到需要用到 Brush 的地方,以上代码不能工作,需要有其他步骤。测试成功后另写博文。


找到如何使Brush可用的方法:

void FGlobalTestStyle::GetResources(TArray<const FSlateBrush*>& OutBrushes) const
{
  OutBrushes.Add(&m_brush);  // 在这里添加需要的所有Brush,必须全部列出;
}

  

------------------------------------------------------ [signature]: 天天都要有收获~ :p ----------
原文地址:https://www.cnblogs.com/LiuxuLisa/p/slate.html