
UE5 Common UI로 구현하는 크로스 플랫폼 UI 네비게이션 및 포커스 관리 완벽 가이드
언리얼 엔진 5의 Common UI 플러그인을 활용하여 PC, 콘솔, 모바일 환경에서 일관된 UI 네비게이션 스택과 게임패드 포커스 제어 시스템을 구축하는 실전 구현 가이드입니다.
TL;DR
Unreal Engine 5의 Common UI 플러그인은 PC, 콘솔(게임패드), 모바일 환경 간의 입력 분기 처리와 포커스 네비게이션을 단일 파이프라인으로 표준화하는 공식 프레임워크입니다.
핵심 컴포넌트인 UCommonActivatableWidgetStack과 UCommonActivatableWidget을 활용하면 화면 전환 시 스택 기반의 수명 주기 관리와 포커스 자동 복원, 플랫폼별 입력 글리프(Glyph) 자동 전환을 최소한의 보일러플레이트로 안정되게 구현할 수 있습니다.
왜 기존 UMG 대신 Common UI를 사용해야 하는가?
기존 언리얼 엔진의 UMG(Unreal Motion Graphics)만을 이용해 크로스 플랫폼 게임을 개발할 때 가장 흔히 겪는 문제는 입력 라우팅(Input Routing)과 게임패드/키보드 포커스 관리(Focus Navigation)입니다.
마우스와 터치는 좌표 기반 클릭으로 동작하지만 콘솔 게임패드와 키보드는 위젯 간의 2차원 방향 이동(Spatial Navigation)과 명시적인 포커스 진입/이탈 처리가 필요합니다. 기존 UMG 방식에서는 서브 메뉴를 열거나 팝업을 띄울 때마다 포커스를 잃어버리는 포커스 유실 버그(Focus Loss)가 빈번하게 발생하며 플랫폼마다 별도의 입력 분기 코드를 작성해야 하는 번거로움이 있었습니다.
Common UI 플러그인은 에픽게임즈가 포트나이트(Fortnite)를 멀티 플랫폼으로 서비스하며 축적한 노하우를 바탕으로 설계된 표준 UI 아키텍처입니다.
UMG와 Common UI 핵심 구성 요소 비교
| 분류 | 기본 UMG (UUserWidget) | Common UI (UCommonUserWidget) | 핵심 장점 |
|---|---|---|---|
| 기본 위젯 | UUserWidget | UCommonActivatableWidget | 활성화/비활성화 수명 주기 관리 및 포커스 스택 연동 |
| 버튼 컴포넌트 | UButton | UCommonButtonBase | 입력 트리거 바인딩, 플랫폼별 버튼 아이콘(Glyph) 자동 변경 |
| 화면 전환 컨테이너 | UWidgetSwitcher | UCommonActivatableWidgetStack | 화면 푸시/팝 시 하위 화면 입력 차단 및 뒤로가기(Back) 자동 처리 |
| 입력 모드 제어 | SetInputModeGameAndUI 수동 호출 | FUIInputConfig 기반 자동 라우팅 | 위젯별 마우스 캡처, 커서 표시, 게임플레이 입력 무시 설정 자동화 |
Common UI 아키텍처와 위젯 스택 흐름
Common UI의 핵심 동작 원리는 액티베이터블 위젯 스택(Activatable Widget Stack) 구조입니다. 최상위 레이어에 등록된 위젯만 입력을 독점적으로 처리하며 하위 위젯은 렌더링 상태를 유지하더라도 입력 수신이 비활성화됩니다.
flowchart TD
A[Root UI Layout Canvas] --> B[Modal Layer Stack]
A --> C[Menu Layer Stack]
A --> D[HUD Layer Stack]
subgraph MenuLayer [Menu Layer Stack 동작 흐름]
C --> M1[Main Menu: Inactive / Input Blocked]
C --> M2[Settings Menu: Active / Focus Owned]
end
M2 -- Back Action 트리거 --> POP[Widget Pop & Deactivate]
POP --> M1_RESTORE[Main Menu Re-activated & Previous Focus Restored]
위 구조를 통해 새로운 팝업이나 서브 메뉴가 스택에 푸시되면 이전 메뉴는 자동으로 입력을 차단당하고 팝업이 닫힐 때 직전에 선택했던 버튼으로 포커스가 원자적으로 복원됩니다.

4단계로 구현하는 크로스 플랫폼 네비게이션
Step 1: 플러그인 활성화 및 입력 설정
Edit -> Plugins에서 Common UI Plugin을 활성화하고 에디터를 재시작합니다.Project Settings -> Engine -> General Settings에서Custom Viewport Client Class를CommonGameViewportClient로 변경합니다.Project Settings -> Game -> Common Input Settings에서 지원할 플랫폼(PC, Xbox, PlayStation, Switch 등)과 컨트롤러 타입별 글리프 데이터(Controller Data Asset)를 등록합니다.
Step 2: C++ 기반 Activatable Widget 및 컨테이너 정의
화면 단위의 UI는 UCommonActivatableWidget을 상속받아 구현합니다.
화면이 활성화될 때 기본 포커스를 받을 위젯을 GetDesiredFocusTarget() 오버라이드로 지정할 수 있습니다.
// Source/MyGame/UI/MyMenuWidget.h
#pragma once
#include "CoreMinimal.h"
#include "CommonActivatableWidget.h"
#include "MyMenuWidget.generated.h"
class UCommonButtonBase;
UCLASS(Abstract, Blueprintable)
class MYGAME_API UMyMenuWidget : public UCommonActivatableWidget
{
GENERATED_BODY()
public:
virtual TOptional<FUIInputConfig> GetDesiredInputConfig() const override;
protected:
virtual UWidget* NativeGetDesiredFocusTarget() const override;
virtual void NativeOnActivated() override;
UPROPERTY(BlueprintReadOnly, meta = (BindWidget))
TObjectPtr<UCommonButtonBase> FirstFocusButton;
};
// Source/MyGame/UI/MyMenuWidget.cpp
#include "UI/MyMenuWidget.h"
#include "CommonButtonBase.h"
#include "Input/UIInputConfig.h"
TOptional<FUIInputConfig> UMyMenuWidget::GetDesiredInputConfig() const
{
// 메뉴 활성화 시 게임플레이 입력을 차단하고 UI 전용 메뉴 모드로 설정
return FUIInputConfig(ECommonInputMode::Menu, EMouseCaptureMode::NoCapture);
}
UWidget* UMyMenuWidget::NativeGetDesiredFocusTarget() const
{
// 패드나 키보드로 화면 진입 시 초기 포커스를 받을 위젯 반환
return FirstFocusButton;
}
void UMyMenuWidget::NativeOnActivated()
{
Super::NativeOnActivated();
// 활성화 시 필요한 초기화 로직 수행
}
Step 3: CommonButtonBase를 이용한 액션 바인딩
UCommonButtonBase를 상속받은 버튼 위젯을 생성하고 위젯 블루프린트 설정의 Input -> Triggering InputAction에 Enhanced Input Action을 매핑합니다.
이렇게 설정하면 마우스 클릭뿐만 아니라 컨트롤러의 특정 버튼(예: A 버튼 또는 Enter 키) 입력 시 자동으로 OnClicked 이벤트가 발생합니다.
Step 4: 백버튼(Back/Escape)과 모달 스택 라우팅
UCommonActivatableWidget의 디테일 패널에서 Is Back Handler를 True로 체크합니다.
스택 최상단 위젯에서 EnhancedInputAction으로 매핑된 취소 액션(예: 게임패드 B 버튼, 키보드 ESC)이 발생하면 별도의 분기 처리 없이도 자동으로 DeactivateWidget()이 호출되며 이전 화면으로 복귀합니다.

실전 트러블슈팅: 자주 발생하는 문제 해결
1. 마우스 조작 후 게임패드 전환 시 포커스가 사라지는 현상
- 원인: 마우스 클릭 시 가상 커서로 인해 네비게이션 포커스가 위젯 외부로 빠져나간 상태에서 입력 장치만 변경되었기 때문입니다.
- 해결책:
UCommonUIActionRouterBase서브시스템이 입력 장치 변경(ECommonInputType)을 감지했을 때 최상위 액티브 위젯의NativeGetDesiredFocusTarget()으로 포커스를 자동 라우팅하도록 설정합니다.
2. 모달 팝업 뒤에 있는 백그라운드 버튼이 상호작용되는 문제
- 원인: 단순
UUserWidget을 Add to Viewport로 올렸을 경우 입력 이벤트가 하위 캔버스로 통과(Pass-through)됩니다. - 해결책: 모든 화면 전환을
UCommonActivatableWidgetStack을 통해 관리하고 팝업 위젯의GetDesiredInputConfig()에서ECommonInputMode::Menu를 반환하여 하위 레이어의 입력을 완전히 차폐합니다.
자주 묻는 질문 (FAQ)
Q1. Enhanced Input과 Common UI는 어떻게 연동되나요?
Common UI는 내부적으로 Enhanced Input과 완벽하게 통합되어 있습니다.
Common UI 액션 라우터는 CommonUI.Action 태그가 지정된 Enhanced Input Action을 가로채어 현재 포커스된 위젯의 바인딩에 우선 전달하며 UI가 소비하지 않은 입력만 플레이어 컨트롤러의 게임플레이 입력으로 전달합니다.
Q2. 플랫폼별 버튼 아이콘(키보드 키, Xbox/PS 패드 버튼)은 어떻게 자동 교체하나요?
CommonInputSettings에 등록된 CommonUIInputData 에셋 내 Controller Data 테이블에 입력 액션별 텍스처(브러시)를 등록해 두면, UCommonActionWidget 컴포넌트가 현재 사용 중인 입력 장치를 감지하여 런타임에 실시간으로 올바른 글리프 텍스처를 교체 렌더링합니다.
Q3. 여러 개의 독립된 UI 레이어(HUD, 알림, 메뉴)를 동시에 운용하려면 어떻게 구성해야 하나요?
전체 뷰포트를 관리하는 루트 레이아웃 위젯에 목적별 UCommonActivatableWidgetStack을 여러 개 배치합니다.
예를 들어 HUDLayerStack, MenuLayerStack, ModalLayerStack으로 계층을 나누고 Z-Order를 분리하여 상위 레이어가 활성화될 때 하위 레이어의 입력만을 선별적으로 일시 정지시킬 수 있습니다.
정리
Common UI 플러그인은 언리얼 엔진 5에서 크로스 플랫폼 게임을 개발할 때 선택이 아닌 필수적인 표준 프레임워크입니다.
UCommonActivatableWidgetStack을 통한 화면 계층화와 UCommonButtonBase의 입력 추상화를 적극 활용하여 모든 플랫폼에서 부드럽고 직관적인 UI 네비게이션 경험을 구축해 보시기 바랍니다.


