How to avoid creating subsystem if a child subsystem exists
Use the following code in ShouldCreateSubsystem
for(auto Class : TObjectRange<UClass>())
{
if(Class->IsChildOf(UMySubsystem::StaticClass()) && Class != UMySubsystem::StaticClass())
{
//A child class exists
return false;
}
}
//No children exist
return true;
(Thanks to Aquanox on the Unreal Discord)
Custom subsystem collections
- Define a custom subclass of
USubsystem
- Create
FSubsystemCollection<UMySubsystem> SubsystemCollection
in the class which you want to manage the lifetime of the subsystems - Run
SubsystemCollection.Initialize(this)
andSubsystemCollection.Deinitialize()
when you want to construct and destroy the subsystems respectively.
Getting custom subsystem instances
You can define a GetSubsystem
function like so, which will allow easy access in blueprints:
UFUNCTION(BlueprintCallable, meta=(DeterminesOutputType=SubsystemClass))
UKotGameStateSubsystem* GetSubsystem(const TSubclassOf<UKotGameStateSubsystem> SubsystemClass) const
{
return SubsystemCollection.GetSubsystem<UKotGameStateSubsystem>(SubsystemClass);
}
Note: It may be possible to extend K2Node_GetSubsystem
. See the other classes extending it.
Subsystems in custom GameStates and Actors
You may want to run Initialize
and Deinitialize
in BeginPlay
and EndPlay
. Initializing subsystems in OnConstruct seems to cause issues when working on files in the editor.
This may apply to other actor types as well.
Note: in UE5 calling Deinitialize
in Destroyed
seems to cause a crash when exiting a packaged game. Use EndPlay
instead.