0. 개요

어빌리티를 업그레이드하기 위해, 업그레이드를 위한 정보를 데이터 에셋으로 저장한다.

 

 

1. 데이터 에셋 생성

하나의 게임플레이 어빌리티에 다양한 업그레이드를 적용할 수 있도록 한다.

 

(1) 데이터 에셋

#pragma once

#include "CoreMinimal.h"
#include "GameplayTagContainer.h"
#include "Engine/DataAsset.h"
#include "AbilityUpgradeInfo.generated.h"

USTRUCT(BlueprintType)
struct FAuraAbilityUpgradeInfo
{
	GENERATED_BODY();

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FString UpgradeName;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FString UpgradeDescription;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	int32 UpgradeMaxLevel = 1;

	// 실제 적용할 효과 타입 (ex. 데미지 +, 쿨다운 감소 등)
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTag UpgradeEffectTag;
};

// 배열로 래핑
USTRUCT(BlueprintType)
struct AURA_API FAuraAbilityUpgradeInfoArray
{
	GENERATED_BODY()

	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Upgrade Info Array")
	TArray<FAuraAbilityUpgradeInfo> UpgradeInfos;
};


UCLASS()
class AURA_API UAbilityUpgradeInfo : public UDataAsset
{
	GENERATED_BODY()

protected:
	virtual void PostLoad() override;
	
public:
	UFUNCTION(BlueprintCallable, BlueprintPure)
	FAuraAbilityUpgradeInfoArray GetUpgradesForAbility(const FGameplayTag& AbilityTag);

	UFUNCTION(BlueprintCallable, BlueprintPure)
	FAuraAbilityUpgradeInfo GetUpgradeInfoForUpgradeTag(const FGameplayTag& UpgradeTag);
	
	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	TMap<FGameplayTag, FAuraAbilityUpgradeInfoArray> AbilityUpgrades;

	// 업그레이드 태그, 업그레이드 정보 키-값 쌍 
	UPROPERTY(Transient) // 런타임에만 생성됨
	TMap<FGameplayTag, FAuraAbilityUpgradeInfo> UpgradeInfosByEffectTag;
};

(1-1) FAuraAbilityUpgradeInfo 구조체

업그레이드에 대한 정보를 가지고 있는 구조체이다.

업그레이드 이름, 업그레이드 태그, 최대 레벨, 설명 등의 정보를 가진다.

이 구조체를 배열로 감싸서 하나의 어빌리티가 다양한 업그레이드 정보를 가지게 할 것이다.

 

 

(1-2) FAuraAbilityUpgradeInfoArray 구조체

언리얼의 UPROPERTY를 이용하는 데이터 에셋 블루프린트에서는 기본적으로 중복된 키를 가지는 값을 등록할 수 없다.

이를 회피하기 위해 업그레이드 정보를 배열로 감싸고, 감싼 배열을 값으로 등록할 것이다.

 

 

(1-3) AbilityUpgradeInfo 클래스

AbilityUpgrades 맵은 어빌리티 태그와 어빌리티 업그레이드 정보 배열의 키-값 쌍으로 이루어져 있다.

 

 

(1-4) 업그레이드 태그-업그레이드 정보 맵

런타임에 UpgradeInfosByEffectTag 구조체를 이용하여 업그레이드 태그와 업그레이드 정보를 연결하여 맵으로 저장해 놓는다.

 

 

 

(2) PostLoad 함수

에셋이 로드되면 호출되는 함수이다.

#include "AbilitySystem/Data/AbilityUpgradeInfo.h"

void UAbilityUpgradeInfo::PostLoad()
{
	Super::PostLoad();

	// 로드된 이후에 한 번만 호출
	UpgradeInfosByEffectTag.Empty();
	for (const auto& Pair : AbilityUpgrades)
	{
		for (const auto& UpgradeInfo : Pair.Value.UpgradeInfos)
		{
			// UpgradeEffectTag가 유효하다면 캐시 맵에 추가
			if (UpgradeInfo.UpgradeEffectTag.IsValid())
			{
				UpgradeInfosByEffectTag.Add(UpgradeInfo.UpgradeEffectTag, UpgradeInfo);
			}
		}
	}
}

어빌리티 업그레이드 배열을 순회하여, 각 업그레이드 태그에 업그레이드 정보를 매칭하고 맵으로 저장한다.

 

 

(3) 어빌리티의 업그레이드 정보 배열을 반환하는 Getter 함수

FAuraAbilityUpgradeInfoArray UAbilityUpgradeInfo::GetUpgradesForAbility(const FGameplayTag& AbilityTag)
{
	if (FAuraAbilityUpgradeInfoArray* FoundInfoArray = AbilityUpgrades.Find(AbilityTag))
	{
		return *FoundInfoArray;
	}
	return FAuraAbilityUpgradeInfoArray();
}

어빌리티 태그를 넣으면 해당 어빌리티에 가능한 업그레이드를 배열로 반환하는 Getter 함수이다.

 

 

(4) 업그레이드 태그와 일치하는 업그레이드 정보를 반환하는 Getter 함수

FAuraAbilityUpgradeInfo UAbilityUpgradeInfo::GetUpgradeInfoForUpgradeTag(const FGameplayTag& UpgradeTag)
{
	if (!UpgradeTag.IsValid())
		return FAuraAbilityUpgradeInfo();
	
	return *UpgradeInfosByEffectTag.Find(UpgradeTag);
}

업그레이드 태그를 넣으면 해당 태그와 일치하는 업그레이드 정보를 반환하는 Getter 함수이다.