UE4子系统

UE4在4.22版本后加入了子系统即Subsystem,子系统是生命周期受控的自动实例化类,非常易用。

概述

目前在4.24版本中,子系统主要分为4大类

  • 引擎UEngineSubsystem

当引擎子系统的模块加载时,子系统将在模块的 Startup() 函数返回后执行 Initialize(),子系统将在模块的 Shutdown() 函数返回后执行 Deinitialize()

通过GEngine访问

1
UMyEngineSubsystem MySubsystem = GEngine->GetEngineSubsystem<UMyEngineSubsystem>();
  • 编辑器UEditorSubsystem

当编辑器子系统的模块加载时,子系统将在模块的 Startup() 函数返回后执行 Initialize(),子系统将在模块的 Shutdown() 函数返回后执行 Deinitialize()

这些子系统可通过GEditor访问

1
UMyEditorSubsystem MySubsystem = GEditor->GetEditorSubsystem<UMyEditorSubsystem>();
  • 游戏实例UGameInstanceSubsystem

生命周期跟随游戏实例的初始化和卸载

可通过UGameInstance访问

1
2
UGameInstance* GameInstance = ...;
UMyGameSubsystem* MySubsystem = GameInstance->GetSubsystem<UMyGameSubsystem>();
  • 本地玩家ULocalPlayerSubsystem

随着本地玩家创建而创建

通过ULocalPlayer访问

1
2
ULocalPlayer* LocalPlayer = ...;
UMyPlayerSubsystem * MySubsystem = LocalPlayer->GetSubsystem();

示例

创建UMyGameInstanceSubsystem继承自UGameInstanceSubsystem

重写基类方法,如下图所示

1
2
3
4
5
6
//返回false就不会自动创建
virtual bool ShouldCreateSubsystem(UObject* Outer) const override { return true; }
//初始化
virtual void Initialize(FSubsystemCollectionBase& Collection)override;
//卸载
virtual void Deinitialize()override;
1
2
3
4
5
6
7
8
void UMyGameInstanceSubsystem::Initialize(FSubsystemCollectionBase& Collection)
{
UE_LOG(LogTemp,Log,TEXT("MySubsystem Initialize!!!!"));
}
void UMyGameInstanceSubsystem::Deinitialize()
{
UE_LOG(LogTemp, Log, TEXT("MySubsystem Deinitialize!!!!"));
}

另外我们手动创建一个继承自UGameInstance的蓝图类

image-20200803100004102

然后我们在子系统里实现一个测试方法

1
2
3
4
UFUNCTION(BlueprintCallable)
void TestPrint();
UPROPERTY(BlueprintReadWrite,EditAnywhere)
int32 Number=0;
1
2
3
4
void UMyGameInstanceSubsystem::TestPrint()
{
UE_LOG(LogTemp,Log,TEXT("Number= %d !!"),Number);
}

在蓝图里默认直接可以得到子系统如下图

image-20200803100155123

在关卡蓝图里测试

image-20200803100224677

得到结果

image-20200803100258176