AgentSkillsCN

Cpp Subsystems

创建UE5子系统、单例或全局管理类。

SKILL.md
--- frontmatter
description: Creating UE5 subsystems, singletons, or global manager classes

UE5 C++ Subsystems

Subsystems provide a clean pattern for creating managers and global systems without subclassing engine classes.

Subsystem Types

TypeParentLifecycleAccess
UEngineSubsystemGEngineEngine lifetimeGEngine->GetEngineSubsystem<T>()
UEditorSubsystemGEditorEditor lifetimeEditor only, not in packaged games
UGameInstanceSubsystemUGameInstanceGame sessionGetGameInstance()->GetSubsystem<T>()
UWorldSubsystemUWorldWorld/LevelGetWorld()->GetSubsystem<T>()
ULocalPlayerSubsystemULocalPlayerPer local playerLocalPlayer->GetSubsystem<T>()

Creating a Subsystem

cpp
// SaveGameSubsystem.h
#pragma once

#include "Subsystems/GameInstanceSubsystem.h"
#include "SaveGameSubsystem.generated.h"

UCLASS()
class MYGAME_API USaveGameSubsystem : public UGameInstanceSubsystem
{
    GENERATED_BODY()

public:
    // Called when subsystem is created
    virtual void Initialize(FSubsystemCollectionBase& Collection) override;

    // Called when subsystem is destroyed
    virtual void Deinitialize() override;

    // Public API
    UFUNCTION(BlueprintCallable, Category = "Save")
    void SaveGame();

    UFUNCTION(BlueprintCallable, Category = "Save")
    void LoadGame();

private:
    UPROPERTY()
    USaveGame* CurrentSaveGame;
};

Accessing Subsystems

cpp
// From any UObject with world context
if (UGameInstance* GI = GetGameInstance())
{
    USaveGameSubsystem* SaveSystem = GI->GetSubsystem<USaveGameSubsystem>();
    SaveSystem->SaveGame();
}

// From Actor
USaveGameSubsystem* SaveSystem = GetGameInstance()->GetSubsystem<USaveGameSubsystem>();

// World subsystem
UMyWorldSubsystem* WorldSub = GetWorld()->GetSubsystem<UMyWorldSubsystem>();

// Local player subsystem
UMyLocalPlayerSubsystem* LPSub = LocalPlayer->GetSubsystem<UMyLocalPlayerSubsystem>();

Benefits Over Singletons

SubsystemsTraditional Singletons
Auto-managed lifecycleManual creation/destruction
Proper GC integrationMemory leak potential
Built-in Blueprint/Python exposureRequires manual exposure
Avoids subclassing engine classesOften requires engine subclassing
Modular/plugin-friendlyTight coupling

Best Practices

PracticeReason
Use GameInstanceSubsystem for session dataPersists across levels
Use WorldSubsystem for level-specific managersCleaned up on level change
Engine subsystems init onceNot per-PIE instance
No Blueprint subclassesUse UDeveloperSettings + DataTables for config
Editor subsystems are editor-onlyCannot use in packaged games

Designer Configuration

Instead of Blueprint subclasses, use:

cpp
// For project settings
UCLASS(config=Game, defaultconfig, meta=(DisplayName="My Game Settings"))
class UMyGameSettings : public UDeveloperSettings
{
    GENERATED_BODY()

public:
    UPROPERTY(Config, EditAnywhere, Category = "Gameplay")
    float DefaultDifficulty = 1.0f;
};

// Access in subsystem
const UMyGameSettings* Settings = GetDefault<UMyGameSettings>();

Documentation: https://dev.epicgames.com/documentation/en-us/unreal-engine/programming-subsystems-in-unreal-engine