icon
6장 : UI 개발

동적 UI 요소 생성 및 기본 관리


지난 절에서 위젯 블루프린트의 기본적인 개념과 정적인 UI 요소(미리 디자인된 버튼, 텍스트 등)를 화면에 띄우는 방법을 알아보았습니다. 하지만 게임에서는 플레이어의 인벤토리에 아이템이 추가되거나, 적이 스폰되거나, 퀘스트 목록이 업데이트되는 등, 게임 상태에 따라 동적으로 생성되거나 변경되어야 하는 UI 요소가 훨씬 많습니다.

이번 절에서는 게임 플레이 중 필요에 따라 UI 위젯을 생성하고 관리하는 동적 UI 요소 생성의 기본 개념과 활용법에 대해 알아보겠습니다.


동적 UI 요소 생성이란 무엇인가?

동적 UI 요소 생성은 미리 위젯 블루프린트에 고정적으로 배치하는 대신, 블루프린트 로직을 통해 런타임(게임 플레이 중)에 UI 위젯을 생성하고 화면에 추가하는 방식을 의미합니다.

예를 들어, 플레이어의 인벤토리 창을 생각해보세요. 인벤토리 슬롯의 수는 고정되어 있을지 몰라도, 각 슬롯에 어떤 아이템이 들어갈지는 게임 플레이 중에 계속 바뀝니다. 또는 플레이어가 획득하는 아이템의 종류와 개수가 정해져 있지 않으므로, 아이템을 획득할 때마다 해당 아이템 아이콘과 이름이 동적으로 인벤토리 UI에 추가되어야 합니다.


동적 UI 요소 생성의 필요성

  • 게임 상태 반영: 게임의 실시간 데이터(인벤토리, 체력, 점수, 퀘스트 목록 등)에 따라 UI를 유연하게 업데이트해야 합니다.
  • 재사용성: 하나의 아이템 슬롯 위젯 블루프린트를 만들어두고, 필요할 때마다 이 위젯을 여러 번 생성하여 인벤토리의 각 슬롯에 배치할 수 있습니다.
  • 메모리 최적화: 모든 가능한 UI 요소를 미리 만들어두는 대신, 현재 필요한 요소만 메모리에 로드하고 화면에 표시할 수 있습니다.
  • 유연한 레이아웃: 동적으로 생성된 요소들을 필요에 따라 Grid Panel, Wrap Box 등 다양한 패널에 추가하여 유동적인 레이아웃을 구성할 수 있습니다.

동적 UI 요소 생성의 기본 단계

동적으로 UI 요소를 생성하고 관리하는 일반적인 과정은 다음과 같습니다.

자식 위젯 블루프린트 생성 (템플릿): 먼저 동적으로 생성될 개별 UI 요소의 '템플릿'이 될 위젯 블루프린트를 만듭니다. 예를 들어, 인벤토리 아이템 하나를 표시할 WBP_InventorySlot 위젯 블루프린트를 생성합니다.

  • 콘텐츠 브라우저에서 마우스 우클릭 > 사용자 인터페이스(User Interface) > 위젯 블루프린트(Widget Blueprint) 선택.
  • UserWidget을 선택하고 이름을 WBP_InventorySlot으로 지정합니다.
  • WBP_InventorySlot 에디터를 열고 Image (아이템 아이콘용), Text (아이템 이름용) 위젯 등을 배치합니다.
  • 이 이미지와 텍스트 위젯들을 선택하고 디테일 패널에서 Is Variable을 체크하여 변수 이름(예: ItemIcon, ItemNameText)을 부여합니다.
  • 컴파일하고 저장합니다.

부모 위젯 블루프린트에 동적 생성 로직 구현: 이제 WBP_InventorySlot들을 담을 메인 인벤토리 위젯(예: WBP_InventoryScreen)을 만듭니다. 여기에 동적으로 슬롯을 추가하는 로직을 구현합니다.

  • WBP_InventoryScreen 위젯 블루프린트를 새로 생성합니다.
  • 디자이너 탭에서 Grid Panel 위젯을 캔버스 패널로 드래그하여 배치합니다. 이 패널에 WBP_InventorySlot들이 동적으로 추가될 것입니다.
  • Grid Panel을 선택하고 디테일 패널에서 Is Variable을 체크하여 이름을 InventoryGrid로 지정합니다.
  • 그래프 탭으로 이동합니다.
  • 예를 들어, 플레이어의 인벤토리 배열(PlayerInventory - F_ItemData 구조체의 배열)이 업데이트될 때마다 인벤토리 UI를 새로고침하는 함수를 만듭니다. (또는 Event Construct에서 초기 로딩)
// WBP_InventoryScreen의 그래프 탭

// Custom Event: RefreshInventoryUI
// Input: PlayerInventory (Array of F_ItemData)
// ----------------------------------------------------
// Clear Children of InventoryGrid (기존 슬롯 모두 제거)
// For Each Loop (PlayerInventory 배열 순회)
//    Create Widget (Class: WBP_InventorySlot, Owning Player: Get Owning Player)
//    Add Child to Grid (Target: InventoryGrid, Content: Create Widget Return Value)
//       Set Row & Column (옵션: 아이템 순서에 따라 그리드 위치 설정)
//
//    // 새로 생성된 슬롯 위젯에 아이템 데이터 적용
//    // Cast To WBP_InventorySlot (Create Widget Return Value)
//    // Call UpdateSlot (WBP_InventorySlot에 미리 정의된 함수)
//    //    Input: F_ItemData (For Each Loop의 Array Element)
  • 위의 의사코드에 따라 블루프린트 노드를 연결합니다.
    • InventoryGrid 변수에서 드래그하여 Clear Children 노드를 호출하여 기존에 그리드에 있던 모든 자식 위젯을 제거합니다.
    • For Each Loop를 사용하여 PlayerInventory 배열의 각 아이템(F_ItemData)에 대해 반복합니다.
    • 루프 바디 내에서 Create Widget 노드를 호출합니다. Widget ClassWBP_InventorySlot을 선택합니다. Owning PlayerGet Owning Player 노드를 연결합니다.
    • 생성된 WBP_InventorySlot 위젯을 InventoryGrid에 추가하기 위해 Add Child to Grid 노드를 호출합니다. TargetInventoryGrid 변수를 연결하고, ContentCreate WidgetReturn Value를 연결합니다.
    • (선택 사항) Add Child to GridRowColumn 핀에 루프의 Index를 기반으로 계산된 값을 연결하여 그리드 내 위치를 지정할 수 있습니다.
    • 가장 중요한 부분: 생성된 WBP_InventorySlot 위젯에 실제 아이템 데이터를 전달하여 표시하도록 해야 합니다. 이를 위해 WBP_InventorySlotUpdateSlot(F_ItemData ItemData)와 같은 커스텀 함수를 미리 만들어두고, 이 함수 안에서 ItemIconItemNameText에 전달받은 ItemData의 값을 적용하는 로직을 구현합니다.
    • WBP_InventoryScreen에서는 Create WidgetReturn ValueCast To WBP_InventorySlot으로 캐스팅한 후, UpdateSlot 함수를 호출하여 For Each LoopArray Element를 연결합니다.

UI를 화면에 추가 및 동적 업데이트 트리거

  • BP_PlayerControllerBP_GameManager와 같은 메인 컨트롤러 블루프린트에서 WBP_InventoryScreen을 생성하여 화면에 추가합니다.
  • 플레이어가 아이템을 획득했을 때 (예: 특정 아이템 액터와 겹쳤을 때), 플레이어 인벤토리 배열에 아이템을 추가하는 로직을 구현하고, 그 뒤에 RefreshInventoryUI 함수를 호출하여 UI를 업데이트합니다.
// BP_PlayerCharacter 또는 BP_PlayerController의 그래프

// Event PickedUpItem (Custom Event, Input: ItemData F_ItemData)
// -----------------------------------------------------------------
// Add ItemData to PlayerInventory Array
//
// Get Widget of Class (WBP_InventoryScreen) (화면에 인벤토리 위젯이 떠있다고 가정)
// Cast To WBP_InventoryScreen
// Call RefreshInventoryUI (Cast 결과에서 호출)
//    Input: PlayerInventory (PlayerCharacter의 인벤토리 배열)

동적 UI 요소 관리의 핵심

  • 재사용 가능한 위젯 템플릿: 동적으로 생성될 모든 개별 요소(아이템 슬롯, 퀘스트 항목 등)는 자체적인 위젯 블루프린트(WBP_InventorySlot)로 만들어야 합니다.
  • 패널 위젯 활용: Grid Panel, Vertical Box, Horizontal Box, Wrap Box 등은 동적으로 추가되는 자식 위젯들을 자동으로 정렬하고 배치하는 데 매우 유용합니다.
  • 데이터 바인딩 및 함수 호출: 생성된 자식 위젯에 데이터를 전달하고 해당 위젯의 로직을 호출하여 위젯이 자신을 올바르게 표시하도록 합니다. (예: UpdateSlot 함수)
  • Clear Children: 동적 UI를 업데이트하기 전에 기존의 자식 위젯들을 제거하고 새로 그리는 패턴이 흔하게 사용됩니다. 이는 UI의 상태를 깔끔하게 초기화하고 중복 생성을 방지합니다.
  • 성능 고려: 매우 많은 수의 위젯을 동적으로 생성/제거해야 하는 경우, ListViewTileView와 같은 가상화(Virtualization)를 지원하는 위젯을 사용하여 성능을 최적화할 수 있습니다. (이는 고급 주제입니다.)

동적 UI 요소 생성 및 관리는 현대 게임 UI 개발의 필수적인 부분입니다. 이를 통해 게임의 복잡한 데이터를 효율적으로 시각화하고, 사용자에게 반응적이고 몰입감 있는 경험을 제공할 수 있습니다.


이번 절에서는 동적 UI 요소 생성의 개념과 그 필요성, 그리고 블루프린트를 이용한 기본 구현 방법에 대해 알아보았습니다. 동적 UI는 게임의 유연성과 확장성을 크게 높이는 중요한 기법입니다.