GameInstanceSubsystem으로 공통 기능 모으기
ProjectDT의 UI 흐름을 중앙화한 방법
본 블로그 작성 글들은, 강의를 목표로 하고 제작되었습니다. 또한 작성된 글의 정보도 틀렸을 수 있으니, 주의해주세요.
여러 Widget과 Actor가 같은 UI 작업을 반복하면 서로를 직접 찾는 코드가 늘어난다. ProjectDT에서는 공통 UI 흐름을 UGameInstanceSubsystem으로 모았다.
왜 Subsystem을 사용하는가?
UGameInstanceSubsystem은 GameInstance와 같은 수명을 가지며 엔진이 자동으로 생성한다. 별도 Singleton 포인터를 직접 만들지 않아도 어디서든 GameInstance를 통해 가져올 수 있다.
UDTUISubsystem* UISubsystem =
GetGameInstance()->GetSubsystem<UDTUISubsystem>();
if (UISubsystem)
{
UISubsystem->ProcessSolvedProblem(
ProblemData,
FVector2D::ZeroVector,
0.0f,
100.0f
);
}
문제 정답 처리 뒤 이어지는 대화, 화이트보드 노드 생성 같은 부수 효과를 Widget마다 복사하지 않고 한 함수로 모을 수 있다.
모든 것을 넣으면 안 된다
Subsystem도 전역 접근이 쉬우므로 책임을 계속 넣다 보면 또 다른 거대한 관리자 클래스가 된다.
- UI 전환과 UI 이벤트는 UI Subsystem
- 저장 슬롯과 현재 SaveGame은 Save Subsystem
- 현재 월드의 승패 규칙은 GameMode
- 플레이어 입력은 PlayerController
수명이 길다는 이유만으로 전투 중 임시 Actor 포인터를 강하게 잡아두면 월드 이동 뒤 오래된 객체가 남을 수 있다. ProjectDT의 MainUI와 WhiteBoard 참조는 TWeakObjectPtr로 보관했다.
Subsystem은 서로 멀리 떨어진 객체를 연결하는 좋은 허브다. 하지만 데이터의 수명과 책임이 정말 GameInstance 범위인지 확인하고 사용해야 한다.