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

  1. Define a custom subclass of USubsystem
  2. Create FSubsystemCollection<UMySubsystem> SubsystemCollection in the class which you want to manage the lifetime of the subsystems
  3. Run SubsystemCollection.Initialize(this) and SubsystemCollection.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.