DEV Community

Cover image for [UE] Subsystem
Seongcheol Jeon
Seongcheol Jeon

Posted on

[UE] Subsystem

  • Subsystem
    • Subsystem 종류
    • Subsystem을 사용하는 이유
    • UEditorSubsystem
    • UGameInstanceSubsystem을 상속받는 클래스의 생명주기 (Life Time)
  • Game Instance vs Game Instance Subsystem

Subsystem

Subsystem 종류

  • UEngineSubsystem
  • UEditorSubsystem
  • UGameInstanceSubsystem
  • ULocalPlayerSubsystem
  • UWorldSubsystem
Subsystem 타입 Life Time
Engine UEngineSubsystem Editor, In-Game

시작
Engine Subsystem의 Module 로드 -> Module의 Startup() 함수 반환 -> Initialize() 호출


Module의 Shutdown() 함수 변환 -> DeInitialize() 호출
Editor UEditorSubsystem Editor 시작 시

시작
Editor Subsystem의 Module이 로드 -> Module의 Startup() 함수 변환 -> Initialize() 호출


Module의 Shutdown() 함수 변환 -> DeInitialize()를 호출:
Game Instance UGameInstanceSubsystem In-Game 시작 ~ In-Game 종료

시작
GameInstance Subsystem의 Module이 로드 -> Module의 Startup() 함수 반환 -> Initialize() 호출


Module의 Shutdown() 함수 반환 -> DeInitialize() 호출
Local Player ULocalPlayerSubsystem ULocalPlayer의 LifeTime
(Level이 여러개면, 해당 Level에 존재하는 ULocalPlayer의 LifeTime)

시작
LocalPlayer Subsystem의 Module 로드 -> Module의 Startup() 함수 변환 -> Initialize() 호출


Module의 Shutdown() 함수 변환 -> DeInitialize() 호출
World UWorldSubsystem UWorld의 LifeTime
(Level이 여러개이면, Level 별로 존재함)
// Engine Subsystem
class UMyEngineSubsystem : public UEngineSubsystem { ... };

UMyEngineSubsystem* MySubsystem = GEngine->GetEngineSubsystem<UMyEngineSubsystem>();


// Editor Subsystem
class UMyEditorSubsystem : public UEditorSubsystem { ... };

UMyEidotrSubsystem* MySubsystem = GEditor->GetEditorSubsystem<UMyEditorSubsystem>();


// GameInstance Subsystem
class UMyGameSubsystem : public UGameInstanceSubsystem { ... };

UGameInstance* GameInstance = GetGameInstance();
UMyGameSubsystem* MySubsystem = GameInstance->GetSubsystem<UMyGameSubsystem>();


// LocalPlayer Subsystem
class UMyPlayerSubsystem : public ULocalPlayerSubsystem { ... };

UGameInstance* GameInstance = GetGameInstance();
ULocalPlayer* LocalPlayer = GameInstance->GetFirstGamePlayer();
UMyPlayerSubsystem* MySubsystem = LocalPlayer->GetSubsystem<UMyPlayerSubsystem>();
Enter fullscreen mode Exit fullscreen mode

Reference

UnrealEngine 프로그래밍 서브시스템
UnrealEngine 프로그래밍 서브시스템 (extra community info)


Subsystem을 사용하는 이유

Subsystem 내에 이미 존재하는 기능을 가져와서 사용하므로 다음과 같은 이점이 있다.

  • Engine Class Override를 피할 수 있다.
  • API 추가를 피할 수 있다.
  • Subsystem 기능이 Blueprint에 자동 노출되고 Blueprint로 Subsystem을 액세스할 수 있다.

UEditorSubsystem

  • UEditorActorSubsystem
    • TArray GetSelectedlevelActors()
    • TArray GetAllLevelActors()

UGameInstanceSubsystem을 상속받는 클래스의 생명주기(Life Time)

// GameInstance Subsystem
class UMyGameSubsystem : public UGameInstanceSubsystem { ... };
Enter fullscreen mode Exit fullscreen mode

위와 같이 UGameInstanceSubsystem을 상속받는 클래스가 존재한다면,

UGameInstance 생성 -> UMyGameSubsystem 인스턴스 생성
UGameInstance 초기화 -> UMyGameSubsystem 인스턴스에서 Initialize()가 호출

UGameInstance 종료 -> UMyGameSubsystem 인스턴스에서 DeInitialize()가 호출
DeInitialize()가 호출된 시점에서 UMyGameSubsystem 인스턴스에 대한 참조가 삭제된다. 더 이상 참조가 없으면 UMyGameSubsystem 인스턴스는 Garbage Collection 대상이 된다.


Game Instance vs Game Instance Subsystem

Game Instance Game Instance Subsystem
Game 생성 시, Spawn 된다. Game Instance가 생성 된 후에 생성된다.
Game이 종료될 때까지 소멸되지 않는다(Game 종료 시, 소멸). Game Instance 종료 시, 소멸되고 Garbage Collector에서 처리된다.

게임에서 레벨을 이동하는 경우(던전 입장, 마을 이동 등)가 빈번하게 발생한다. 또한 FPS 게임의 경우, 한 게임이 끝나고 다시 게임이 시작되는 경우가 비번히 발생한다.

그렇기 때문에 Game이 종료 될 때까지 소멸하지 않는 Game Instance보다 **Game Instance Subsystem을 사용하는 것이 더 유리하다.**

Game Instance Subsystem을 사용하면, Engine Class Override를 피할 수 있고 코드의 재사용성을 높일 수 있다.

Top comments (0)