PART 2 · 강의 1/3

CommonUI 아키텍처

멀티 플랫폼 UI 프레임워크인 CommonUI의 플러그인 구성, 노드 트리 구조, 기존 UMG와의 차이점을 학습합니다.

01

CommonUI란 무엇인가

기존 UMG의 한계와 CommonUI가 해결하는 문제

CommonUI는 Epic Games가 Fortnite 개발 경험에서 탄생시킨 멀티 플랫폼 UI 프레임워크입니다. 기존 UMG의 입력 처리, 포커스 관리, 플랫폼별 UI 대응의 어려움을 체계적으로 해결합니다.

기존 UMG의 한계

  • - 입력 라우팅이 위젯 계층에 종속
  • - 게임패드 포커스 관리가 수동적
  • - 플랫폼별 분기 코드가 산재
  • - 메뉴 스택 관리 로직을 직접 구현
  • - 입력 디바이스 전환 감지 어려움

CommonUI의 해결책

  • + 노드 기반 입력 라우팅 시스템
  • + 자동 포커스 관리 내장
  • + 플랫폼별 입력 아이콘 자동 전환
  • + Activatable Widget 스택 관리
  • + 입력 디바이스 변경 자동 감지
UE 5.5+ 주요 변경사항

UE 5.5부터 PushWidget()이 위젯 활성화를 내부적으로 처리합니다. 이전 버전처럼 PushWidget() 후에 수동으로 ActivateWidget()을 호출하면 초기화 로직이 깨질 수 있으니 주의하세요.

02

플러그인 설정

CommonUI 플러그인 활성화와 프로젝트 구성

1단계: 플러그인 활성화

Edit → Plugins에서 Common UI 플러그인을 활성화합니다. 연관된 CommonInput 플러그인도 함께 활성화됩니다.

2단계: Build.cs 모듈 추가

Build.cs
// MyGame.Build.cs PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "UMG", "SlateCore", "Slate", "CommonUI", // CommonUI 핵심 모듈 "CommonInput", // 입력 처리 모듈 });

3단계: GameViewportClient 설정

C++ - CommonUI 게임 뷰포트
// DefaultEngine.ini에서 뷰포트 클래스 변경 [/Script/Engine.Engine] GameViewportClientClassName=/Script/CommonUI.CommonGameViewportClient // 또는 C++에서 커스텀 뷰포트 클래스 생성 UCLASS() class UMyGameViewportClient : public UCommonGameViewportClient { GENERATED_BODY() };
필수 설정

UCommonGameViewportClient를 사용하지 않으면 CommonUI의 입력 라우팅이 정상 동작하지 않습니다. 이 뷰포트 클래스가 Slate 입력 이벤트를 가로채서 CommonUI의 노드 트리로 전달하는 역할을 합니다.

03

노드 트리 구조

CommonUI의 핵심 - 위젯을 노드로 변환하는 입력 트리

CommonUI는 위젯을 노드(Node)로 변환하여 입력 라우팅 트리를 구성합니다. 이 트리는 Slate 위젯 계층과 유사하지만, 입력 처리 목적에 특화된 별도의 논리적 계층입니다.

[Common UI Action Router] — 루트 입력 라우터
  └─ [Root Node]
      ├─ [Game Layer] — 게임플레이 입력
      └─ [Menu Layer] — UI 입력
          ├─ [Main Menu Widget] — Activatable
          │   ├─ [Settings Panel] — Activatable
          │   └─ [Confirm Dialog] — Activatable
          └─ [Popup Stack]
C++ - CommonUI 핵심 클래스 계층
// CommonUI 주요 클래스 관계 UCommonUserWidget // UUserWidget 확장 - 모든 CommonUI 위젯의 베이스 └─ UCommonActivatableWidget // 활성화/비활성화 가능 위젯 UCommonButtonBase // CommonUI 버튼 (입력 아이콘 자동 전환) UCommonTextBlock // 플랫폼별 스타일 지원 텍스트 UCommonActionWidget // 입력 액션 아이콘 표시 UCommonUIActionRouterBase // 입력 라우팅 관리자 UCommonGameViewportClient // CommonUI 전용 뷰포트
노드 트리 vs 위젯 트리

일반 Slate 위젯 트리는 모든 위젯이 레이아웃과 렌더링에 참여하지만, CommonUI 노드 트리는 입력을 받을 수 있는 위젯만 노드로 등록됩니다. 입력 이벤트는 트리의 가장 깊은 활성 노드에서 시작하여 위로 전파되며, 각 노드가 입력을 소비하거나 통과시킬 수 있습니다.

04

UCommonUserWidget 기본 사용

CommonUI의 기본 위젯 클래스 활용법

C++ - UCommonUserWidget 서브클래스
UCLASS() class UMyCommonWidget : public UCommonUserWidget { GENERATED_BODY() public: virtual void NativeConstruct() override; protected: // CommonUI의 입력 액션 등록 // RegisterUIActionBinding()으로 위젯 내 액션 바인딩 void RegisterInputActions(); UPROPERTY(meta = (BindWidget)) UCommonButtonBase* BackButton; UPROPERTY(meta = (BindWidget)) UCommonActionWidget* BackActionWidget; }; void UMyCommonWidget::NativeConstruct() { Super::NativeConstruct(); // CommonButtonBase는 플랫폼에 따라 자동으로 // 마우스 클릭 / 게임패드 버튼 아이콘을 전환합니다 BackButton->OnClicked().AddUObject( this, &UMyCommonWidget::HandleBackAction); }
기존 UMG 클래스 CommonUI 대응 클래스 추가 기능
UUserWidget UCommonUserWidget 입력 액션 등록, 노드 트리 참여
UButton UCommonButtonBase 플랫폼별 아이콘, 선택/포커스 상태
UTextBlock UCommonTextBlock 플랫폼별 스타일, 스크롤 텍스트
(직접 구현) UCommonActivatableWidget 활성화 스택, 자동 포커스 관리
SUMMARY

핵심 요약

  • CommonUI는 기존 UMG의 입력 관리, 포커스, 멀티 플랫폼 대응 한계를 해결하는 상위 레벨 UI 프레임워크입니다
  • 플러그인 활성화 후 UCommonGameViewportClient를 설정해야 입력 라우팅이 정상 동작합니다
  • CommonUI는 위젯을 노드 트리로 구성하여 입력 이벤트를 체계적으로 라우팅합니다
  • UCommonUserWidget, UCommonButtonBase, UCommonActivatableWidget이 핵심 클래스입니다
  • UE 5.5+에서는 PushWidget()이 활성화를 자동 처리하므로 수동 ActivateWidget() 호출을 피해야 합니다
PRACTICE

도전 과제

배운 내용을 직접 실습해보세요

실습 1: CommonUI 플러그인 활성화 및 초기 설정

프로젝트에 CommonUI, CommonInput 플러그인을 활성화하고, CommonGameViewportClient를 설정하세요. UCommonGameInstance를 상속하여 게임 인스턴스를 구성하고 정상 작동을 확인합니다.

실습 2: CommonUI 기본 위젯 계층 구성

UCommonActivatableWidget을 상속한 메인 메뉴 위젯을 만들고, UCommonButtonBase를 사용하여 '게임 시작', '설정', '종료' 버튼이 있는 메뉴 화면을 구성해 보세요.

심화 과제

기존 UMG 기반 UI를 CommonUI로 마이그레이션하는 계획을 수립하고 실행하세요. GameViewportClient 교체, ActivatableWidget 전환, Input Routing 적용 등 단계별로 진행합니다.