오늘은 언리얼 엔진 UMG를 사용해 상점(Shop) UI를 설계·구현한 과정을 정리해 보았습니다. 특히 아이템별 개별 위젯 구성, 구매/판매 가격 분리, 아이템 ID 관리, Vertical List 기반 아이템 나열에 초점을 두고 작업을 진행하였습니다. 본 문서는 추후 상점 기능을 확장하거나 다른 인벤토리/상점 UI를 설계할 때 참고 자료로 활용하기 위해 작성하였습니다.
UImage* ItemImageUTextBlock* ItemNameTextUTextBlock* BuyPriceTextUTextBlock* SellPriceTextUButton* BuyButtonUButton* SellButtonTObjectPtr<UTexture2D> ItemIconFText ItemNameint32 BuyPriceint32 SellPriceint32 ItemId 또는 FName ItemId (프로젝트 상황에 맞게 선택)SetItemDisplayData(UTexture2D* InIcon, const FText& InName, int32 InBuyPrice, int32 InSellPrice, int32 InItemId)SetButtonsEnabled(bool bEnableBuy, bool bEnableSell)NativeOnInitialized()에서 버튼 클릭 바인딩BuyButton->OnClicked.AddDynamic(this, &UCMShopContentElementWidget::HandleBuyClicked);SellButton->OnClicked.AddDynamic(this, &UCMShopContentElementWidget::HandleSellClicked);OnBuyRequested.Broadcast(this);OnSellRequested.Broadcast(this);GetBuyPrice() / GetSellPrice()GetItemName() / GetItemIcon()GetItemId()TArray<FCMShopItem>를 기준으로 리스트를 생성하도록 설계ItemID: 아이템 고유 식별자 (int32)BuyPrice: 구매 가격SellPrice: 판매 가격Quantity: 수량 (스택 수, 재고 등 다양한 용도로 확장 가능)ItemName: UI 표시용 이름ItemIcon: UI 표시용 아이콘 텍스처BlueprintType, EditAnywhere, BlueprintReadWrite로 설정VerticalBox 안에 여러 UCMShopContentElementWidget을 동적으로 생성하여 리스트를 구성ShopItemListBoxUVerticalBox*BindWidget 이름과 동일하게 배치ShopItemWidgetClassTSubclassOf<UCMShopContentElementWidget>ShopItemsTArray<FCMShopItem>UCMShopWidget(const FObjectInitializer& ObjectInitializer)NativeOnInitialized()에서 초기 리스트 빌드 호출BuildShopList();ShopItems를 미리 세팅해 둔 경우 바로 UI에 리스트가 생성되도록 구성BuildShopList)ShopItemListBox 또는 ShopItemWidgetClass가 유효하지 않으면 조기 리턴ShopItemListBox->ClearChildren();ShopItems 배열을 순회하며 다음 작업 수행CreateWidget<UCMShopContentElementWidget>(this, ShopItemWidgetClass)로 엘리먼트 위젯 생성SetItemDisplayData로 이미지/이름/구매·판매 가격/ID 설정OnBuyRequested, OnSellRequested 델리게이트를 메인 위젯의 핸들러에 바인딩ShopItemListBox->AddChild(ElementWidget)으로 VerticalBox에 추가UVerticalBoxSlot로 캐스팅해 정렬, 패딩 등 레이아웃 세부 설정SetShopItems)TArray<FCMShopItem>을 넘겨받아 ShopItems를 교체BuildShopList() 재호출로 UI를 바로 갱신HandleElementBuyRequested(UCMShopContentElementWidget* ElementWidget)ElementWidget->GetItemId()와 GetBuyPrice()로 어떤 아이템인지, 얼마인지 확인HandleElementSellRequested(UCMShopContentElementWidget* ElementWidget)ElementWidget->GetItemId()와 GetSellPrice()를 사용UCMShopWidget 기반)VerticalBox 추가 후 이름을 ShopItemListBox로 지정ShopItemWidgetClass에 UCMShopContentElementWidget 기반 BP를 할당ShopItems 배열에 몇 개의 아이템 데이터 직접 입력해 즉시 미리보기 가능하게 설정UCMShopContentElementWidget 기반)ItemImageItemNameTextBuyPriceTextSellPriceTextBuyButtonSellButtonBindWidgetOptional 속성과 이름이 일치하도록 관리해 자동 바인딩 확인오늘은 언리얼 엔진 UMG를 사용해 상점 UI를 설계하고, 아이템 단위 위젯과 상점 메인 위젯 사이의 책임을 분리하는 구조를 구현해 보았습니다. 아이템 이미지, 이름, 구매/판매 가격, 그리고 식별용 ID까지 한 번에 관리할 수 있도록 설계함으로써 추후 실제 게임 데이터 및 인벤토리 시스템과의 연동이 훨씬 수월해질 것으로 기대하고 있습니다.
향후에는 오늘 설계한 UI 구조를 기반으로 실제 골드, 인벤토리, 툴팁, 필터링/정렬 기능 등을 추가하여 보다 완성도 높은 상점 시스템으로 확장해 나갈 계획입니다. 오늘의 정리가 이후 작업에 도움이 되기를 바랍니다.