Subsystem
Table of contents
Explanation
For the sake of convenience Systems Architecture provides handy wrapper over
USystemsWorld
global instances as a USystemsSubsystem
that is basically a registry of systems worlds accessible from any place in the code.
All user needs to do is to register and setup systems world using
USystemsSubsystem::AcquireSystemsWorld
when certain game phase starts
(either game, level, menu, etc) before adding/removing/querying actor components, and
unregister systems world using USystemsSubsystem::ReleaseSystemsWorld
when given game phase ends.
Examples
The most common game phases where systems might exists are game instance and game mode.
- You register systems world in game instance when there are systems are possible to run during entire game lifetime. This is the easiest and safest option.
- You register systems world in game mode when there are systems that are possible to run during given game level lifetime. This is useful if we for example have completely separate pipelines set for each level or game mode.
Game instance
Since game instance has a lifetime of entire game run, we only care here about
registering systems world to subsystem on UGameInstance::Init
.
UCLASS()
class EXAMPLE_API UExampleGameInstance : public UGameInstance
{
GENERATED_BODY()
private:
virtual void Init() override;
};
void UExampleGameInstance::Init()
{
Super::Init();
auto* Subsystem = USystemsSubsystem::Get(GetWorld());
if (IsValid(Subsystem))
{
Subsystem->AcquireSystemsWorld(FName(),
[&](auto& Systems)
{
Systems.RegisterComponent<UShiaComponent>();
Systems.InstallResource<UShiaSettings>();
Systems.InstallLambdaSystem(JustDoItSystem, FInstallSystemOptions("JustDoIt"));
});
}
}
Game mode
When it comes to game mode, we should register systems world on AGameModeBase::InitGame
(it runs before any actor BeginPlay
- if we register it on BeginPlay
, then some
actors placed on level might try to register to yet non-existing systems world) and
unregister it on AGameModeBase::EndPlay
.
UCLASS()
class EXAMPLE_API AExampleGameMode : public AGameModeBase
{
GENERATED_BODY()
private:
virtual void InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage) override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
};
void AExampleGameMode::InitGame(const FString& MapName, const FString& Options, FString& ErrorMessage)
{
Super::InitGame(MapName, Options, ErrorMessage);
auto* Subsystem = USystemsSubsystem::Get(GetWorld());
if (IsValid(Subsystem))
{
Subsystem->AcquireSystemsWorld(FName(),
[&](auto& Systems)
{
Systems.RegisterComponent<UShiaComponent>();
Systems.InstallResource<UShiaSettings>();
Systems.InstallLambdaSystem(JustDoItSystem, FInstallSystemOptions("JustDoIt"));
});
}
}
void AExampleGameMode::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
Super::EndPlay(EndPlayReason);
auto* Subsystem = USystemsSubsystem::Get(GetWorld());
if (IsValid(Subsystem))
{
Subsystem->ReleaseSystemsWorld(ThisClass::SYSTEMS_WORLD);
}
}
Documentation built with Unreal-Doc
v1.0.8 tool by PsichiX