PART 5 · 강의 2/3

Data Binding

게임 데이터와 UI를 효율적으로 연결하는 바인딩 패턴을 학습합니다

01

Property Binding

위젯 속성에 함수를 직접 바인딩하여 자동 갱신

Property Binding은 위젯 속성 옆의 Bind 드롭다운에서 함수를 선택하여, 해당 속성이 매 프레임 함수의 반환값으로 갱신되게 하는 방법입니다.

Property Binding Example // ProgressBar의 Percent 속성에 바인딩 // Details > Percent > Bind > Create Binding [Function: Get Health Percent] └──> [Get Owning Player Pawn] └──> [Cast to BP_Player] └──> [Get Health Component] └──> [GetHealthPercent] └──> Return Value (Float: 0.0 ~ 1.0)
Property Binding의 성능 문제

Property Binding은 매 프레임 실행됩니다. 바인딩 함수 안에서 Cast, Get All Actors 등 비용이 큰 연산을 수행하면 성능이 크게 저하됩니다. 이벤트 기반 업데이트가 더 효율적이므로, Property Binding은 간단한 계산에만 사용하세요.

02

이벤트 기반 업데이트

Event Dispatcher를 활용한 효율적인 UI 갱신

이벤트 기반 업데이트는 데이터가 변경될 때만 UI를 갱신합니다. Property Binding보다 훨씬 효율적이며, 권장되는 패턴입니다.

Event-Driven UI Update // WBP_HUD: Event Construct에서 바인딩 설정 [Event Construct] │ ├──> [Get Owning Player Pawn] ──> [Cast to BP_Player] │ │ │ ├──> [Promote to Variable] (PlayerRef) │ │ │ └──> [Get Health Component] │ │ │ └──> [Bind Event to OnHealthChanged] │ └─ Event: [Custom Event: HandleHealthChanged] │ └──> (초기 UI 값 설정) // 데이터 변경 시에만 실행됨 (매 프레임 X) [HandleHealthChanged] (NewHealth: Float, Delta: Float) ├──> [Set Percent] (HealthBar, NewHealth / MaxHealth) ├──> [Set Text] (HealthText, NewHealth) └──> [Branch: Delta < 0] └─ True ──> [Play Animation] (DamageFlash)

바인딩 방식 비교

방식갱신 빈도성능적합한 경우
Property Binding매 프레임낮음항상 변하는 단순 값 (FPS 카운터)
Event Dispatcher데이터 변경 시높음대부분의 게임 UI (체력, 점수, 인벤토리)
Timer주기적중간주기적 폴링 (서버 상태, 시간)
03

위젯 애니메이션

UMG 애니메이션으로 동적인 UI 효과를 구현합니다

Widget Animation 생성

Designer 탭 하단의 Animations 섹션에서 + Animation으로 생성합니다. 타임라인 기반으로 위젯의 속성을 키프레임으로 애니메이션합니다.

Widget Animation Example // 애니메이션: FadeIn Anim_FadeIn (Length: 0.5s) └─ Track: Canvas Panel - Render Opacity ├─ Key 0.0s: Opacity = 0.0 └─ Key 0.5s: Opacity = 1.0 // 애니메이션: DamageFlash Anim_DamageFlash (Length: 0.3s) └─ Track: DamageOverlay (Image) - Color and Opacity ├─ Key 0.0s: A = 0.0 ├─ Key 0.1s: A = 0.5 (빨간색 플래시) └─ Key 0.3s: A = 0.0 // 블루프린트에서 재생 [Play Animation] ├─ In Animation: Anim_FadeIn ├─ Start at Time: 0.0 ├─ Num Loops to Play: 1 (0 = 무한) └─ Play Mode: Forward / Reverse / PingPong
애니메이션 가능한 속성

Render Transform (Position, Scale, Shear, Angle), Render Opacity, Color and Opacity, Visibility 등 대부분의 위젯 속성을 애니메이션할 수 있습니다. 위젯 이름 왼쪽의 Is Variable 체크를 활성화해야 애니메이션 트랙에 추가할 수 있습니다.

04

사용자 위젯 (User Widget)

재사용 가능한 위젯 컴포넌트 만들기

자주 반복되는 UI 요소(아이템 슬롯, 스탯 행, 버프 아이콘)를 별도의 User Widget으로 만들어 재사용합니다.

Reusable User Widget Pattern // WBP_ItemSlot - 재사용 가능한 아이템 슬롯 위젯 WBP_ItemSlot // 변수 (Instance Editable, Expose on Spawn): ├─ ItemData: S_ItemData ├─ SlotIndex: Integer │ // 위젯 구조: ├─ Button (SlotButton) │ └─ Overlay │ ├─ Image (ItemIcon) │ ├─ Text (QuantityText) │ └─ Image (RarityBorder) │ // 함수: ├─ SetItemData(NewData: S_ItemData) │ ├─ Set Icon Texture │ ├─ Set Quantity Text │ └─ Set Border Color by Rarity │ // 이벤트: └─ OnSlotClicked (Event Dispatcher) // 인벤토리에서 동적으로 슬롯 생성: [ForEachLoop: InventoryItems] └──> [Create Widget] (WBP_ItemSlot) ├─ ItemData: Array Element └──> [Add Child to Wrap Box] (InventoryGrid)
Is Variable 체크

위젯을 블루프린트에서 참조하려면 Designer에서 해당 위젯의 Is Variable 체크박스를 활성화해야 합니다. 이렇게 해야 Graph 탭에서 해당 위젯의 노드(Set Text, Set Visibility 등)를 사용할 수 있습니다.

SUMMARY

핵심 요약

  • Property Binding은 매 프레임 실행되므로 간단한 계산에만 사용한다
  • 이벤트 기반 업데이트(Event Dispatcher)가 성능과 유지보수에서 가장 권장된다
  • UMG Animation으로 위젯 속성을 키프레임 기반으로 애니메이션한다
  • 반복되는 UI 요소는 User Widget으로 분리하여 재사용한다
  • 블루프린트에서 위젯을 참조하려면 Is Variable 체크를 활성화해야 한다
  • Create Widget + Add Child로 런타임에 동적으로 UI를 생성한다
PRACTICE

도전 과제

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

실습 1: Property Binding으로 체력바 구현

ProgressBar의 Percent 속성에 Property Binding을 생성하세요. 캐릭터의 CurrentHP/MaxHP 비율을 반환하는 함수를 바인딩하고, 체력 변화에 따라 자동으로 바가 변하는지 확인하세요. 색상도 체력에 따라 초록 → 노랑 → 빨강으로 변하도록 바인딩하세요.

실습 2: 이벤트 기반 UI 업데이트

Property Binding 대신 이벤트 디스패처로 UI를 업데이트하세요. 캐릭터에서 OnHealthChanged 디스패처를 발생시키고, 위젯에서 이 이벤트를 Bind하여 Set Percent로 직접 업데이트합니다. 두 방식의 성능 차이를 비교하세요.

심화 과제

ViewModel 패턴을 블루프린트로 구현하세요. 별도의 BP_HUDViewModel 오브젝트에 표시할 데이터(HP, MP, 경험치, 레벨)를 모아두고, 위젯은 ViewModel만 참조하여 데이터를 표시합니다. 데이터 변경 시 이벤트 디스패처로 UI에 통보하는 MVVM 구조를 만드세요.