1. 업그레이드 카드
(1) 뷰(View) 구성

업그레이드 제목, 설명, 최대 레벨 수를 표시하는 카드 UI를 만든다.
(2) 뷰 모델(View Model) 구성
#pragma once
#include "CoreMinimal.h"
#include "GameplayTagContainer.h"
#include "MVVMViewModelBase.h"
#include "MVVM_AbilityCard.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnUpgradeSelected, FGameplayTag, SelectedUpgradeTag);
struct FGameplayTag;
UCLASS()
class AURA_API UMVVM_AbilityCard : public UMVVMViewModelBase
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly)
FGameplayTag UpgradeTag;
UPROPERTY()
int32 CardIndex;
public:
FOnUpgradeSelected OnUpgradeSelectedDelegate;
public:
FString GetUpgradeName() const { return UpgradeName; }
FString GetUpgradeDescription() const { return UpgradeDescription; }
int32 GetUpgradeMaxLevel() const { return UpgradeMaxLevel; }
void SetUpgradeName(FString InUpgradeName);
void SetUpgradeDescription(FString InUpgradeDescription);
void SetUpgradeMaxLevel(int32 InUpgradeMaxLevel);
UFUNCTION(BlueprintCallable)
void UpgradeButtonClicked();
private:
/*필드 노티파이*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, FieldNotify, Setter, Getter, meta =(AllowPrivateAccess="true"))
FString UpgradeName;
UPROPERTY(EditAnywhere, BlueprintReadWrite, FieldNotify, Setter, Getter, meta =(AllowPrivateAccess="true"))
FString UpgradeDescription;
UPROPERTY(EditAnywhere, BlueprintReadWrite, FieldNotify, Setter, Getter, meta =(AllowPrivateAccess="true"))
int32 UpgradeMaxLevel;
};
이름, 정보, 최대 레벨의 정보를 필드 노티파이를 이용하여 나타낼 것이다.
- MVVM 모델에서 뷰 모델의 한계
뷰 모델은 모델(Model), 즉 데이터를 가공하지 않고, 데이터를 뷰로 전달하는 역할만 한다.
따라서 버튼을 클릭하면 델리게이트를 이용하여 모델 내에서 데이터를 가공하고 반영하도록 해야 한다.
#include "UI/ViewModel/MVVM_AbilityCard.h"
void UMVVM_AbilityCard::SetUpgradeName(FString InUpgradeName)
{
UE_MVVM_SET_PROPERTY_VALUE(UpgradeName, InUpgradeName);
}
void UMVVM_AbilityCard::SetUpgradeDescription(FString InUpgradeDescription)
{
UE_MVVM_SET_PROPERTY_VALUE(UpgradeDescription, InUpgradeDescription);
}
void UMVVM_AbilityCard::SetUpgradeMaxLevel(int32 InUpgradeMaxLevel)
{
UE_MVVM_SET_PROPERTY_VALUE(UpgradeMaxLevel, InUpgradeMaxLevel);
}
void UMVVM_AbilityCard::UpgradeButtonClicked()
{
// 바인딩은 플레이어 컨트롤러에서!!
OnUpgradeSelectedDelegate.Broadcast(UpgradeTag);
}
매크로를 사용하여 값을 Set 하도록 설정해야 한다.
2. 카드 선택 UI
(1) 뷰 구성

위의 카드 슬롯을 세 개 배치한다.
(2) 뷰 모델 구성
#pragma once
#include "CoreMinimal.h"
#include "MVVMViewModelBase.h"
#include "MVVM_CardSelection.generated.h"
class UMVVM_AbilityCard;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FEnableSelectButton, bool, bEnable);
UCLASS()
class AURA_API UMVVM_CardSelection : public UMVVMViewModelBase
{
GENERATED_BODY()
public:
void InitializeSlot();
public:
UFUNCTION(BlueprintPure)
UMVVM_AbilityCard* GetCardViewModelByIndex(int32 Index);
int32 GetNumCards() { return AbilityCards.Num(); }
public:
UPROPERTY(EditDefaultsOnly)
TSubclassOf<UMVVM_AbilityCard> AbilityCardViewModelClass;
private:
UPROPERTY()
TMap<int32, UMVVM_AbilityCard*> AbilityCards;
UPROPERTY()
TObjectPtr<UMVVM_AbilityCard> Card_0;
UPROPERTY()
TObjectPtr<UMVVM_AbilityCard> Card_1;
UPROPERTY()
TObjectPtr<UMVVM_AbilityCard> Card_2;
};
세 개의 카드의 뷰 모델을 저장하여 가지고 있도록 한다. 맵에 각 인덱스 별로 하나 씩 지정한다.
#include "UI/ViewModel/MVVM_CardSelection.h"
#include "AuraGameplayTags.h"
#include "UI/ViewModel/MVVM_AbilityCard.h"
void UMVVM_CardSelection::InitializeSlot()
{
Card_0 = NewObject<UMVVM_AbilityCard>(this, AbilityCardViewModelClass);
Card_0->CardIndex = 0;
Card_0->UpgradeTag = FAuraGameplayTags::Get().Abilities_None;
Card_1 = NewObject<UMVVM_AbilityCard>(this, AbilityCardViewModelClass);
Card_1->CardIndex = 1;
Card_1->UpgradeTag = FAuraGameplayTags::Get().Abilities_None;
Card_2 = NewObject<UMVVM_AbilityCard>(this, AbilityCardViewModelClass);
Card_2->CardIndex = 2;
Card_2->UpgradeTag = FAuraGameplayTags::Get().Abilities_None;
AbilityCards.Add(0, Card_0);
AbilityCards.Add(1, Card_1);
AbilityCards.Add(2, Card_2);
}
UMVVM_AbilityCard* UMVVM_CardSelection::GetCardViewModelByIndex(int32 Index)
{
return AbilityCards.FindChecked(Index);
}
업그레이드 카드의 뷰 모델 클래스를 이용하여 업그레이드 카드의 뷰 모델을 생성한 이후, 각 카드 슬롯의 인덱스와 업그레이트 태그를 초기화한다.
(3) 카드 선택 UI에 뷰 모델 연결

(3-1) 부모 변경
카드 선택 UI인 WBP_CardSelection의 부모를 LoadScreenWidget 클래스를 상속받는 WBP_CardSelection_Base를 생성하여 이로 교체한다.
LoadScreenWidget 클래스는 이전에 불러오기 UI에서 사용한 MVVM 모델의 위젯 중 기본적인 클래스이다.
(3-2) WBP_CardSelection_Base에서 뷰 모델 찾기 함수

HUD에 저장된 카드 선택 UI의 뷰 모델을 가져와 반환한다.
위의 과정을 통해 카드 선택 UI가 올바른 뷰 모델을 가지게 되었다.
(4) WBP_CardSelection 이벤트 그래프

저장된 카드 위젯(뷰)들에 대해 카드를 초기화하는 함수를 호출한다.
(4-1) WBP_UpgradeCard에 뷰 모델 할당하기

카드의 뷰 모델은 Manual로 생성하여 따로 지정할 것이다.
(4-2) 뷰 모델의 블루프린트 버전 생성

카드 선택 UI의 블루프린트 버전을 생성하고 어빌리티 카드의 뷰 모델의 클래스를 지정한다.
카드의 블루프린트 버전을 생성한다.
(4-3) WBP_UpgradeCard의 InitializeCard 함수

카드의 뷰 모델을 Manual로 지정하기로 했기 때문에, Set MVVM Ability Card 함수를 사용해 뷰 모델을 직접 지정해야 한다.
WBP_UpgradeCard와 WBP_CardSelection의 부모는 WBP_CardSelection_Base 로 되어 있기 때문에, Find Card Selection View Model 함수를 사용할 수 있다.
이 함수를 사용해 카드 선택 UI의 뷰 모델에 접근해서 맵에서 카드 슬롯 인덱스와 매칭된 뷰 모델을 꺼내와서 업그레이드 카드의 뷰 모델을 가져올 수 있다.
- 카드 선택 UI의 뷰 모델을 하위 뷰 모델에서 참조해도 되는가?
카드의 뷰 모델을 가져오기 위해, 상위 뷰 모델의 맵을 참조하는 것은 약한 종속성을 가지기 때문에 괜찮다.
단, 추후에 상위 UI의 뷰 모델을 참조하지 않는 방향을 유지해야 한다.
'UE 5 스터디 > Gameplay Ability System(GAS)' 카테고리의 다른 글
| 32-5. 로그 라이크 - (3) 게임플레이 어빌리티 - (1) 어빌리티 재구조화 및 업그레이드 기능 적용 (1) | 2025.06.09 |
|---|---|
| 32-4. 로그 라이크 - (2) MVVM - (2) 뷰 생성 및 초기화, UI와 게임 연동 (0) | 2025.06.09 |
| 32-2. 로그 라이크 - (1) 데이터 에셋 - (2) 데이터 에셋 블루프린트 생성 및 사용 (0) | 2025.06.09 |
| 32-1. 로그 라이크 - (1) 데이터 에셋 - (1) 어빌리티 업그레이드 (0) | 2025.06.09 |
| 32. 로그 라이크 설계 (0) | 2025.06.09 |
