UE Subsystems学习笔记

UE Subsystems

前言

文章内容取自Subsystems,本篇文章只是云笔记,请看原文章进行学习

定义:

Subsystems是一套可以定义自动实例化和释放的类的框架。这个框架允许你从5类里选择一个来定义子类(只能在C++定义):

  1. UEngineSubsystem
    • UEngine* GEngine
  2. UEditorSubsystem
    • UEditorEngine* GEditor
  3. UGameInstanceSubsystem
    • UGameInstance* GameInstance
  4. UWorldSubsystem
    • UWorld* World
  5. ULocalPlayerSubsystem
    • ULocalPlayer* LocalPlayer

优点

  • 自动实例化
    • 这些的UMyXXXSubsystem类,会在合适的时机被创建出对象,然后在合适的时机释放,这个过程是自动化的。不需要自己手写创建代码。也不需要自己显式的定义变量,Subsystems已经定义好方便友好的访问接口了。
  • 托管生命周期
    • 根据你选择的父类不同,引擎会为创建出来的Subsystem实现出不同的生命周期。因此官方文档里会称这5个父类为5个不同的生命周期。根据你选择的生命周期不同,Initialize()Deinitialize()会自动的在合适的时机被调用。一个Subystem类型也有可能根据需要被自动的被创建出多个实例。这些里面的繁琐逻辑自己都不用操心。

使用:

重载函数

virtual bool ShouldCreateSubsystem(UObject* Outer) const override { return true; }
virtual void Initialize(FSubsystemCollectionBase& Collection)override;
virtual void Deinitialize()override;

C++访问

//UMyEngineSubsystem获取
UMyEngineSubsystem* MySubsystem = GEngine->GetEngineSubsystem<UMyEngineSubsystem>();

//UMyEditorSubsystem的获取
UMyEditorSubsystem* MySubsystem = GEditor->GetEditorSubsystem<UMyEditorSubsystem>();

//UMyGameInstanceSubsystem的获取
UGameInstance* GameInstance = UGameplayStatics::GetGameInstance(...);
UMyGameInstanceSubsystem* MySubsystem = GameInstance->GetSubsystem<UMyGameInstanceSubsystem>();

//UMyWorldSubsystem的获取
UWorld* World=MyActor->GetWorld();  //world用各种方式也都可以
UMyWorldSubsystem* MySubsystem=World->GetSubsystem<UMyWorldSubsystem>();

//UMyLocalPlayerSubsystem的获取
ULocalPlayer* LocalPlayer = Cast<ULocalPlayer>(PlayerController->Player)
UMyLocalPlayerSubsystem * MySubsystem = LocalPlayer->GetSubsystem<UMyLocalPlayerSubsystem>();
//我省略了一些宏标记和注释,因为函数名字是不言自明的。
UCLASS()
class ENGINE_API USubsystemBlueprintLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()
public:
    static UEngineSubsystem* GetEngineSubsystem(TSubclassOf<UEngineSubsystem> Class);
    static UGameInstanceSubsystem* GetGameInstanceSubsystem(UObject* ContextObject, TSubclassOf<UGameInstanceSubsystem> Class);
    static ULocalPlayerSubsystem* GetLocalPlayerSubsystem(UObject* ContextObject, TSubclassOf<ULocalPlayerSubsystem> Class);
    static UWorldSubsystem* GetWorldSubsystem(UObject* ContextObject, TSubclassOf<UWorldSubsystem> Class);
    static ULocalPlayerSubsystem* GetLocalPlayerSubSystemFromPlayerController(APlayerController* PlayerController, TSubclassOf<ULocalPlayerSubsystem> Class);
};

生命周期:

  • UGameInstanceSubsystem: 数量1。依赖于GameInstance的生命周期,从游戏的启动开始创建,游戏退出时销毁。这里的一场游戏指的是Runtime或PIE模式的运行的都算,一场游戏里可能会创建多个World切换。
  • UWorldSubsystem: 数量可能>1。依赖于UWorld,一般情况下生命周期与GameMode一样, 切换关卡会销毁和创建。但编辑器模式下视口里的场景其实也是个World,其生命周期与Editor一样。
  • UEditorSubsystem: 只在编辑器模式下存在, 数量1。依赖于GEditor, 从编辑器启动开始创建,到编辑器退出时销毁。
  • UEngineSubsystem: 依赖于GEngine, Editor或Runtime模式都是全局唯一。从进程启动开始创建,进程退出时销毁。
  • ULocalPlayerSubsystem: 数量取决于LocalPlayer数量。依赖于ULocalPlayer,一般情况下生命周期与GameInstance一致。

UEngineSubsystem和UEditorSubsystem属于UDynamicSubsystem,可以根据Module的加载释放来创建销毁

用法:

1.遍历

const TArray<USourceControlSubsystem*>& systems= GEngine->GetEngineSubsystemArray<USourceControlSubsystem>();

2.蓝图继承

C++创建抽象基类–>蓝图继承抽象基类–>显式加载蓝图基类

UCLASS(abstract, Blueprintable, BlueprintType)
class HELLO_API UMyGameInstanceSubsystemBase : public UGameInstanceSubsystem
{
}

UObject* bpAsset = LoadObject<UObject>(NULL, TEXT("/Game/BP_MyGameInstanceSubsystem.BP_MyGameInstanceSubsystem_C"));

3.同一个BaseType下的多个Subsystem可以定义依赖顺序

任务系统依赖于计分系统

void UMyTaskSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
    //初始化依赖项
    Collection.InitializeDependency(UMyScoreSubsystem::StaticClass());
    //获取
    UMyScoreSubsystem* ss=((FSubsystemCollection<UGameInstanceSubsystem>&)Collection).GetSubsystem<UMyScoreSubsystem>(UMyScoreSubsystem::StaticClass());
}

4.Tick

UCLASS()
class HELLO_API UMyTickSubsystem : public UGameInstanceSubsystem,public FTickableGameObject
{
    GENERATED_BODY()
public:
    virtual void Tick(float DeltaTime) override;
    virtual bool IsTickable() const override { return !IsTemplate(); }//不是CDO才Tick
    virtual TStatId GetStatId() const override{RETURN_QUICK_DECLARE_CYCLE_STAT(UMyScoreSubsystem, STATGROUP_Tickables);}
};

参考

Subsystems

猜你喜欢

转载自blog.csdn.net/qq_52179126/article/details/131860744