二、使用WidgetStyle设置样式
SlAiStyle.h
#pragma once
#include "CoreMinimal.h"
#include"SlateBasics.h"
/**
*
*/
//模仿单例模式
class SLAICOURSE_API SlAiStyle
{
public:
static void Initialize();
//获取游戏中注册样式的名字
static FName GetStyleSetName();
//游戏关闭时调用,取消注册
static void ShutDown();
//外部调用,获取SlAiStyle唯一实例(单例)
static const ISlateStyle& Get();
private:
//FSlateStyleSet用来注册样式(Slate 外观的命名属性集合)
static TSharedRef<class FSlateStyleSet> Create();
static TSharedPtr<FSlateStyleSet> SlAiStyleInstance;
};
SlAiStyle.cpp
#include "SlAiStyle.h"
#include <Slate/SlateGameResources.h>
TSharedPtr<FSlateStyleSet> SlAiStyle::SlAiStyleInstance = nullptr;
void SlAiStyle::Initialize()
{
if (!SlAiStyleInstance.IsValid()) {
SlAiStyleInstance = Create();
//FSlateStyleRegistry是可用于跟踪和管理slate style data的中央存储库。
//注册(添加)一个集合样式块
FSlateStyleRegistry::RegisterSlateStyle(*SlAiStyleInstance);
}
}
FName SlAiStyle::GetStyleSetName()
{
//FName 系统需要
//FString 最耗资源,可变化
//FText 文本本地化
static FName SlateSetName(TEXT("SlAiStyle"));
return SlateSetName;
}
void SlAiStyle::ShutDown()
{
//取消注册
FSlateStyleRegistry::UnRegisterSlateStyle(*SlAiStyleInstance);
ensure(SlAiStyleInstance.IsUnique());
//Reset() :重置此共享指针,删除对对象的引用。 如果没有其他共享对对象的引用,那么它将被销毁。
SlAiStyleInstance.Reset();
}
const ISlateStyle& SlAiStyle::Get()
{
// TODO: 在此处插入 return 语句
return *SlAiStyleInstance;
}
TSharedRef<class FSlateStyleSet> SlAiStyle::Create()
{
//New(SlAiStyle::GetStyleSetName(), "/Game/UI/Style", "/Game/UI/Style") 创建范围为/Game/UI/Style 的新 Slate 资源集。
StyleRef 可以引用该目录下的Slate资源
TSharedRef<FSlateStyleSet> StyleRef = FSlateGameResources::New(SlAiStyle::GetStyleSetName(), "/Game/UI/Style", "/Game/UI/Style");
return StyleRef;
}
SlAiCourse.h
#pragma once
#include "CoreMinimal.h"
class FSlAiCourceModule :public FDefaultModuleImpl
{
public:
//在加载模块 DLL 并创建模块对象后立即调用
virtual void StartupModule() override;
//在模块卸载之前调用,就在模块对象被销毁之前调用。
//在正常关闭期间,这以模块完成 StartupModule() 的相反顺序调用。
virtual void ShutdownModule() override;
};
SlAiCourse.cpp
#include "SlAiCourse.h"
#include "Modules/ModuleManager.h"
#include "SlAiStyle.h"
void FSlAiCourceModule::StartupModule()
{
//初始化样式
//避免重复加载
FSlateStyleRegistry::UnRegisterSlateStyle(SlAiStyle::GetStyleSetName());
SlAiStyle::Initialize();
}
void FSlAiCourceModule::ShutdownModule()
{
SlAiStyle::ShutDown();
}
IMPLEMENT_PRIMARY_GAME_MODULE( FSlAiCourceModule, SlAiCourse, "SlAiCourse" );
SlAiMenuWidgetStyle.h
#pragma once
#include "CoreMinimal.h"
#include "Styling/SlateWidgetStyle.h"
#include "SlateWidgetStyleContainerBase.h"
#include"SlateBrush.h"
#include "SlAiMenuWidgetStyle.generated.h"
/**
*
*/
USTRUCT()
struct SLAICOURSE_API FSlAiMenuStyle : public FSlateWidgetStyle
{
GENERATED_USTRUCT_BODY()
FSlAiMenuStyle();
virtual ~FSlAiMenuStyle();
// FSlateWidgetStyle
virtual void GetResources(TArray<const FSlateBrush*>& OutBrushes) const override;
static const FName TypeName;
virtual const FName GetTypeName() const override {
return TypeName; };
static const FSlAiMenuStyle& GetDefault();
//HUD背景图片
UPROPERTY(EditAnywhere, Category = MenuHUD)
FSlateBrush MenuHUDBackgroundBrush;
};
/**
*/
UCLASS(hidecategories=Object, MinimalAPI)
class USlAiMenuWidgetStyle : public USlateWidgetStyleContainerBase
{
GENERATED_BODY()
public:
/** The actual data describing the widget appearance. */
UPROPERTY(Category=Appearance, EditAnywhere, meta=(ShowOnlyInnerProperties))
FSlAiMenuStyle WidgetStyle;
virtual const struct FSlateWidgetStyle* const GetStyle() const override
{
return static_cast< const struct FSlateWidgetStyle* >( &WidgetStyle );
}
};
SlAiMenuWidgetStyle.cpp------未变
#include "SlAiMenuWidgetStyle.h"
FSlAiMenuStyle::FSlAiMenuStyle()
{
}
FSlAiMenuStyle::~FSlAiMenuStyle()
{
}
const FName FSlAiMenuStyle::TypeName(TEXT("FSlAiMenuStyle"));
const FSlAiMenuStyle& FSlAiMenuStyle::GetDefault()
{
static FSlAiMenuStyle Default;
return Default;
}
void FSlAiMenuStyle::GetResources(TArray<const FSlateBrush*>& OutBrushes) const
{
// Add any brush resources here so that Slate can correctly atlas and reference them
}
SlAiMenuHUDWidget.h
#pragma once
#include "CoreMinimal.h"
#include "Widgets/SCompoundWidget.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:
//获取Menu样式
const struct FSlAiMenuStyle* MenuStyle;
};
SlAiMenuHUDWidget.cpp
#include "SSlAiMenuHUDWidget.h"
#include "SlateOptMacros.h"
#include"SButton.h"
#include"SImage.h"
#include "SlAiStyle.h"
#include "SlAiMenuWidgetStyle.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");
ChildSlot
[
SNew(SImage)
.Image(&MenuStyle->MenuHUDBackgroundBrush)
];
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
在UE4编辑界面创建Slate控件样式
继承于SlAiMenuWidgetStyle
名称为BPSlAiMenuStyle
位置 内容目录下创建UI文件夹,UI中再创建一个Style文件夹。
MenuStyle
SlAiCourse模组开始时,初始化SlAiStyle样式实例SlAiStyleInstance,
SlAiStyleInstance 通过以下方法创建
FSlateGameResources::New(SlAiStyle::GetStyleSetName(), "Game/UI/Style", "Game/UI/Style");
New(SlAiStyle::GetStyleSetName(), “Game/UI/Style”, “Game/UI/Style”) 创建范围为Game/UI/Style 的新 Slate 资源集。(至于为什么这样可以看源码,里面有eg)
SlAiStyleInstance 可以引用该目录下的Slate资源。
MenuStyle 通过以下表达式赋值
MenuStyle = &SlAiStyle::Get().GetWidgetStyle<FSlAiMenuStyle>("BPSlAiMenuStyle");
SlAiStyle::Get().GetWidgetStyle(“BPSlAiMenuStyle”)
BPSlAiMenuStyle 要获取的资源名称 ,
在Game/UI/Style 范围的名为BPSlAiMenuStyle 的资源就是MenuStyle所引用的资源。
注意:
SlAiStyleInstance.IsUnique()//不要写成SlAiStyleInstance->IsUnique()
//FSlAiCourceModule替换FDefaultModuleImpl
IMPLEMENT_PRIMARY_GAME_MODULE( FSlAiCourceModule, SlAiCourse, "SlAiCourse" );
SNew(SImage)
//不要忘了加&
.Image(&MenuStyle->MenuHUDBackgroundBrush)
运行成功但是图片加载不出来:
BPSlAiMenuStyle创建的位置Game/UI/Style。
//Game前/不能少
FSlateGameResources::New(SlAiStyle::GetStyleSetName(), "/Game/UI/Style", "/Game/UI/Style");