PART 1 · 강의 2/3

레이아웃 패널

UMG의 레이아웃 시스템을 구성하는 핵심 패널 위젯들의 동작 원리와 Slot 시스템을 학습합니다.

01

레이아웃 시스템 기본 원리

Slate의 2-Pass 레이아웃 알고리즘과 Slot 개념

UMG/Slate의 레이아웃은 2-Pass 알고리즘으로 동작합니다. 첫 번째 패스에서 각 위젯의 Desired Size(희망 크기)를 바텀업으로 계산하고, 두 번째 패스에서 실제 할당된 공간 내에서 자식 배치(Arrange)를 탑다운으로 수행합니다.

Pass 1
ComputeDesiredSize
(Bottom-Up)
Pass 2
ArrangeChildren
(Top-Down)
Result
최종 위치 & 크기
결정

Slot 시스템

모든 패널 위젯은 자식을 Slot(슬롯)에 배치합니다. Slot은 자식 위젯에 대한 레이아웃 메타데이터(Padding, Alignment, Size 규칙 등)를 담고 있는 래퍼입니다. 패널 종류에 따라 Slot이 제공하는 옵션이 달라집니다.

C++ - Slot 시스템 구조
// UPanelWidget은 자식을 UPanelSlot에 담아 관리 class UPanelWidget : public UWidget { GENERATED_BODY() protected: UPROPERTY() TArray<UPanelSlot*> Slots; }; // 각 패널은 고유한 Slot 타입을 정의 // CanvasPanel -> UCanvasPanelSlot (앵커, 오프셋, 정렬) // HorizontalBox -> UHorizontalBoxSlot (Fill, 정렬, Padding) // VerticalBox -> UVerticalBoxSlot (Fill, 정렬, Padding)
02

주요 패널 위젯

게임 UI에서 가장 많이 사용되는 레이아웃 패널들

Canvas Panel

자식 위젯을 앵커(Anchor) 기반의 절대/상대 좌표로 배치합니다. 가장 유연한 패널이지만, 반응형 레이아웃을 직접 관리해야 합니다.

C++ - Canvas Panel 사용
// C++에서 CanvasPanel에 위젯 추가 UCanvasPanel* Canvas = WidgetTree->ConstructWidget<UCanvasPanel>(); UTextBlock* Text = WidgetTree->ConstructWidget<UTextBlock>(); Text->SetText(FText::FromString("Hello!")); UCanvasPanelSlot* Slot = Canvas->AddChildToCanvas(Text); Slot->SetAnchors(FAnchors(0.5f, 0.5f)); // 중앙 앵커 Slot->SetAlignment(FVector2D(0.5f, 0.5f)); // 피봇 중앙 Slot->SetPosition(FVector2D(0.f, 0.f)); // 앵커로부터 오프셋
앵커(Anchor) 이해하기

앵커는 0~1 범위의 정규화된 좌표로 부모 영역 내 기준점을 설정합니다. (0,0)은 좌상단, (1,1)은 우하단입니다. 앵커 최소값과 최대값이 다르면 위젯이 부모 크기에 따라 늘어나는(stretch) 동작을 합니다.

Horizontal / Vertical Box

자식을 수평(가로) 또는 수직(세로)으로 순서대로 배치합니다. 가장 많이 사용되는 레이아웃 패널입니다.

Slot 프로퍼티 설명 값 범위
Size Rule Auto(내용 크기) 또는 Fill(남은 공간 비율) Auto / Fill
Fill Size Fill 모드에서 남은 공간 차지 비율 0.0 ~ N
HAlign / VAlign 슬롯 내 자식 정렬 Left/Center/Right/Fill
Padding 슬롯 내 여백 FMargin (상하좌우)
C++ - Vertical Box 레이아웃
UVerticalBox* VBox = WidgetTree->ConstructWidget<UVerticalBox>(); // 자식 1: Auto 크기 (내용에 맞춤) UTextBlock* Title = WidgetTree->ConstructWidget<UTextBlock>(); UVerticalBoxSlot* TitleSlot = VBox->AddChildToVerticalBox(Title); TitleSlot->SetSize(FSlateChildSize(ESlateSizeRule::Automatic)); // 자식 2: Fill 크기 (나머지 공간 모두 차지) UScrollBox* Content = WidgetTree->ConstructWidget<UScrollBox>(); UVerticalBoxSlot* ContentSlot = VBox->AddChildToVerticalBox(Content); ContentSlot->SetSize(FSlateChildSize(ESlateSizeRule::Fill)); ContentSlot->SetHorizontalAlignment(EHorizontalAlignment::HAlign_Fill);
03

특수 패널 위젯

Overlay, Grid Panel, Wrap Box, Size Box의 활용

Overlay

자식 위젯을 겹쳐서(스택) 배치합니다. Z-Order 순서로 렌더링되며, 배경 위에 전경 요소를 겹치는 데 사용됩니다. 각 자식의 HAlign/VAlign으로 정렬을 제어합니다.

Grid Panel

행과 열로 구성된 격자 레이아웃입니다. 각 자식은 Row/Column 인덱스를 지정받습니다. Column Fill과 Row Fill로 비율 설정이 가능합니다.

Wrap Box

자식을 수평으로 배치하다 공간이 부족하면 다음 줄로 줄바꿈합니다. 인벤토리 아이템 그리드나 태그 목록에 적합합니다.

Size Box

단일 자식의 크기를 강제합니다. Width/Height Override, Min/Max 크기를 지정할 수 있습니다. 위젯의 Desired Size를 덮어쓸 때 사용합니다.

C++ - Overlay로 체력바 UI 구성
// Overlay: 배경 이미지 + 프로그레스바 + 텍스트를 겹침 UOverlay* HPOverlay = WidgetTree->ConstructWidget<UOverlay>(); // 레이어 1: 배경 이미지 UImage* BgImage = WidgetTree->ConstructWidget<UImage>(); UOverlaySlot* BgSlot = HPOverlay->AddChildToOverlay(BgImage); BgSlot->SetHorizontalAlignment(EHorizontalAlignment::HAlign_Fill); // 레이어 2: HP 프로그레스바 UProgressBar* HPBar = WidgetTree->ConstructWidget<UProgressBar>(); HPBar->SetPercent(0.75f); HPOverlay->AddChildToOverlay(HPBar); // 레이어 3: HP 텍스트 (중앙 정렬) UTextBlock* HPText = WidgetTree->ConstructWidget<UTextBlock>(); UOverlaySlot* TextSlot = HPOverlay->AddChildToOverlay(HPText); TextSlot->SetHorizontalAlignment(EHorizontalAlignment::HAlign_Center); TextSlot->SetVerticalAlignment(EVerticalAlignment::VAlign_Center);
04

패널 선택 가이드

상황에 따른 최적의 패널 위젯 선택 기준

사용 시나리오 추천 패널 이유
HUD 요소 자유 배치 Canvas Panel 앵커 기반 절대 위치 지정이 가능
목록 형태의 UI Vertical Box 세로 나열에 최적화, Auto/Fill 크기 조정
탭/버튼 행 Horizontal Box 가로 나열에 최적화
배경 + 전경 겹침 Overlay 위젯 스택 구성에 적합
인벤토리 그리드 Wrap Box / Grid Panel 격자 배치 또는 자동 줄바꿈
위젯 크기 고정 Size Box 자식 크기를 강제로 지정
성능 팁: 패널 중첩 최소화

패널을 깊게 중첩하면 레이아웃 계산 비용이 증가합니다. 특히 Canvas Panel 내부에 불필요한 Vertical/Horizontal Box를 중첩하지 마세요. 가능한 한 최소한의 패널 깊이로 원하는 레이아웃을 구성하는 것이 성능에 유리합니다.

SUMMARY

핵심 요약

  • Slate 레이아웃은 ComputeDesiredSize(바텀업)ArrangeChildren(탑다운)의 2-Pass 알고리즘으로 동작합니다
  • 모든 패널 위젯은 고유한 Slot 타입을 가지며, Slot이 자식의 배치 규칙(Padding, Alignment, Size)을 결정합니다
  • Canvas Panel은 앵커 기반 자유 배치, Horizontal/Vertical Box는 방향 기반 순차 배치에 사용됩니다
  • Overlay는 위젯 겹침, Wrap Box는 자동 줄바꿈, Size Box는 크기 강제에 활용됩니다
  • 패널 중첩 깊이를 최소화하여 레이아웃 연산 비용을 줄이는 것이 성능 최적화의 기본입니다
PRACTICE

도전 과제

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

실습 1: 레이아웃 패널 조합 실습

CanvasPanel 위에 VerticalBox와 HorizontalBox를 중첩 배치하여 '상단 메뉴바 + 좌측 사이드바 + 중앙 콘텐츠' 레이아웃을 Widget Blueprint로 구성해 보세요. Anchor와 Alignment 설정을 다양하게 실험합니다.

실습 2: Slot 프로퍼티 동적 제어

C++에서 UHorizontalBoxSlot의 FillWidth, Padding, HAlign, VAlign 값을 런타임에 변경하는 코드를 작성하고, 화면 크기 변경 시 자동 적응하는 반응형 레이아웃을 구현해 보세요.

심화 과제

SPanel을 상속하여 원형 배치(Radial Layout) 패널을 C++로 구현하세요. OnArrangeChildren()에서 자식 위젯들을 원형으로 배치하고, UWidget으로 래핑하여 UMG 에디터에서 사용할 수 있게 만듭니다.