Data Binding
게임 데이터와 UI를 효율적으로 연결하는 바인딩 패턴을 학습합니다
Property Binding
위젯 속성에 함수를 직접 바인딩하여 자동 갱신
Property Binding은 위젯 속성 옆의 Bind 드롭다운에서 함수를 선택하여, 해당 속성이 매 프레임 함수의 반환값으로 갱신되게 하는 방법입니다.
// 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은 매 프레임 실행됩니다. 바인딩 함수 안에서 Cast, Get All Actors 등 비용이 큰 연산을 수행하면 성능이 크게 저하됩니다. 이벤트 기반 업데이트가 더 효율적이므로, Property Binding은 간단한 계산에만 사용하세요.
이벤트 기반 업데이트
Event Dispatcher를 활용한 효율적인 UI 갱신
이벤트 기반 업데이트는 데이터가 변경될 때만 UI를 갱신합니다. Property Binding보다 훨씬 효율적이며, 권장되는 패턴입니다.
// 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 | 주기적 | 중간 | 주기적 폴링 (서버 상태, 시간) |
위젯 애니메이션
UMG 애니메이션으로 동적인 UI 효과를 구현합니다
Widget Animation 생성
Designer 탭 하단의 Animations 섹션에서 + Animation으로 생성합니다. 타임라인 기반으로 위젯의 속성을 키프레임으로 애니메이션합니다.
// 애니메이션: 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 체크를 활성화해야 애니메이션 트랙에 추가할 수 있습니다.
사용자 위젯 (User Widget)
재사용 가능한 위젯 컴포넌트 만들기
자주 반복되는 UI 요소(아이템 슬롯, 스탯 행, 버프 아이콘)를 별도의 User Widget으로 만들어 재사용합니다.
// 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)
위젯을 블루프린트에서 참조하려면 Designer에서 해당 위젯의 Is Variable 체크박스를 활성화해야 합니다. 이렇게 해야 Graph 탭에서 해당 위젯의 노드(Set Text, Set Visibility 등)를 사용할 수 있습니다.
핵심 요약
- Property Binding은 매 프레임 실행되므로 간단한 계산에만 사용한다
- 이벤트 기반 업데이트(Event Dispatcher)가 성능과 유지보수에서 가장 권장된다
- UMG Animation으로 위젯 속성을 키프레임 기반으로 애니메이션한다
- 반복되는 UI 요소는 User Widget으로 분리하여 재사용한다
- 블루프린트에서 위젯을 참조하려면 Is Variable 체크를 활성화해야 한다
- Create Widget + Add Child로 런타임에 동적으로 UI를 생성한다
도전 과제
배운 내용을 직접 실습해보세요
ProgressBar의 Percent 속성에 Property Binding을 생성하세요. 캐릭터의 CurrentHP/MaxHP 비율을 반환하는 함수를 바인딩하고, 체력 변화에 따라 자동으로 바가 변하는지 확인하세요. 색상도 체력에 따라 초록 → 노랑 → 빨강으로 변하도록 바인딩하세요.
Property Binding 대신 이벤트 디스패처로 UI를 업데이트하세요. 캐릭터에서 OnHealthChanged 디스패처를 발생시키고, 위젯에서 이 이벤트를 Bind하여 Set Percent로 직접 업데이트합니다. 두 방식의 성능 차이를 비교하세요.
ViewModel 패턴을 블루프린트로 구현하세요. 별도의 BP_HUDViewModel 오브젝트에 표시할 데이터(HP, MP, 경험치, 레벨)를 모아두고, 위젯은 ViewModel만 참조하여 데이터를 표시합니다. 데이터 변경 시 이벤트 디스패처로 UI에 통보하는 MVVM 구조를 만드세요.