TIL

[UE5] ProjectFT#4 허브 시스템 리팩터링

think95592 2026. 7. 8. 20:23

 

리팩터링을 진행한 이유

허브 시스템을 구현하면서 하나의 Actor가 너무 많은 역할을 담당하고 있다는 문제를 발견했다.

특히 Terminal Actor가

  • UI 열기
  • 퀘스트 처리
  • 상점 처리
  • 데이터 관리

까지 담당하면서 책임이 점점 커지고 있었다.

유지보수와 확장성을 고려하여 각 기능의 책임을 분리하는 방향으로 리팩터링을 진행하였다.


Terminal Actor 책임 축소

기존 구조에서는 Terminal Actor가 대부분의 허브 기능을 직접 처리했다.

Terminal Actor
├─ UI 생성
├─ 퀘스트 처리
├─ 상점 처리
├─ 데이터 조회
└─ 화면 전환

리팩터링 이후에는 Terminal Actor가

플레이어와의 상호작용만 담당하도록 변경하였다.

Terminal Actor
        │
        ▼
UIManager

Terminal은 UI를 열어 달라고 요청만 하고,

실제 기능은 다른 시스템에서 처리하도록 역할을 줄였다.


QuestBoard Actor 제거 방향

초기에는 QuestBoard Actor가

  • 퀘스트 데이터 관리
  • 완료 여부 확인
  • UI 갱신

등을 직접 처리하도록 설계했다.

하지만 퀘스트 로직은 특정 Actor보다 게임 전체에서 공통으로 사용하는 기능에 가까웠다.

그래서 QuestBoard Actor는 점차 제거하고,

퀘스트 관련 로직은 ObjectiveSubsystem으로 이동하는 방향을 결정하였다.

Actor는 단순한 상호작용 지점만 담당하도록 변경하였다.


ObjectiveSubsystem 도입

퀘스트와 목표 시스템을 하나의 Subsystem에서 관리하도록 구조를 변경하였다.

ObjectiveSubsystem

├─ 현재 목표 관리
├─ 퀘스트 완료 검사
├─ 보상 지급
├─ 다음 퀘스트 진행
└─ 진행 상태 저장

이 구조를 통해

  • 여러 Actor가 동일한 퀘스트 정보를 사용할 수 있고
  • UI도 동일한 데이터를 참조할 수 있으며
  • 퀘스트 로직을 한곳에서 관리할 수 있게 되었다.

Terminal → UI → ViewModel → Subsystem 구조

리팩터링 이후 전체 흐름은 다음과 같이 변경하였다.

Player
        │
        ▼
Terminal Actor
        │
        ▼
UIManager
        │
        ▼
MainWidget
        │
        ▼
ViewModel
        │
        ▼
ObjectiveSubsystem

각 계층의 역할은 다음과 같다.

Terminal Actor

  • 플레이어 상호작용 처리
  • UI 열기 요청

UI

  • 화면 표시
  • 사용자 입력 처리

ViewModel

  • UI에 필요한 데이터 가공
  • UI와 게임 로직 연결

ObjectiveSubsystem

  • 실제 퀘스트 및 목표 데이터 관리
  • 게임 진행 로직 처리

리팩터링 후 얻은 점

이번 리팩터링을 통해 가장 크게 느낀 점은 "기능을 어디에 구현할 것인가" 보다 "누가 책임져야 하는가" 가 더 중요하다는 것이었다.

Actor는 상호작용만 담당하고,

UI는 화면 표시만 담당하며,

ViewModel은 데이터를 가공하고,

Subsystem은 실제 게임 로직을 관리하도록 역할을 분리하면서 클래스 간 의존성을 줄일 수 있었다.

또한 기능이 추가되더라도 기존 구조를 크게 수정하지 않고 확장할 수 있는 구조를 만들 수 있었다.