Meta Attribute
현재까지의 GameplayEffect를 통한 데미지 적용 방식은 하드코딩된 방식이었음.
하지만 실제 게임에선, 데미지를 두고 캐릭터간의 능력치를 통한 계산을 거친 값을 적용함.
- Attribute를 직접 바꾸기보다는 중간 계산을 위한 일종의 임시(Placeholder) Attribute를 제작하여, 해당 Attribute를 통해 필요한 계산을 다 마친 후 그 값을 적용하는 방식을 사용함.
이러한 임시 Attribute를 Meta Attribute라고 부름.

AuraAttributeSet에 Meta Attribute 개념을 적용하기 위한 준비를 한다.
// AuraAttributeSet.h
/* Meta Attributes Start */
UPROPERTY(BlueprintReadOnly, Category = "Meta Attributes")
FGameplayAttributeData IncomingDamage;
ATTRIBUTE_ACCESSORS(UAuraAttributeSet, IncomingDamage);
/*Meta Attributes End */
// AuraAttributeSet.cpp
void UAuraAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
Super::PostGameplayEffectExecute(Data);
FEffectProperties EffectProperties;
SetEffectProperties(Data, EffectProperties);
if (Data.EvaluatedData.Attribute == GetHealthAttribute())
{
SetHealth(FMath::Clamp(GetHealth(), 0.f, GetMaxHealth()));
}
if (Data.EvaluatedData.Attribute == GetManaAttribute())
{
SetMana(FMath::Clamp(GetMana(), 0.f, GetMaxMana()));
}
// Attribute가 IncomingDamage인 경우인지를 검사
if (Data.EvaluatedData.Attribute == GetIncomingDamageAttribute())
{
const float LocalIncomingDamage = GetIncomingDamage();
SetIncomingDamage(0.f);
if (LocalIncomingDamage > 0.f)
{
const float NewHealth = GetHealth() - LocalIncomingDamage;
SetHealth(FMath::Clamp(NewHealth, 0.f, GetMaxHealth()));
const bool bFatal = NewHealth <= 0.f;
// Something to do when getting Fatal Damage
}
}
}
Modifier→Modifier Magnitude→Modifier Op 을 ‘Set By Caller’로 변경한다.```cpp
/* Damage Tag */
FGameplayTag Damage;
GameplayTags.Damage = UGameplayTagsManager::Get()
.AddNativeGameplayTag(FName("Damage"),
FString("Damage"));
```void UAuraProjectileSpell::SpawnProjectile(const FVector& ProjectileTargetLocation)
{
// ...
const UAbilitySystemComponent* SourceASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(GetAvatarActorFromActorInfo());
const FGameplayEffectSpecHandle SpecHandle = SourceASC->MakeOutgoingSpec(DamageEffectClass, GetAbilityLevel(), SourceASC->MakeEffectContext());
FAuraGameplayTags GameplayTags = FAuraGameplayTags::Get();
// SetByCaller
UAbilitySystemBlueprintLibrary::AssignTagSetByCallerMagnitude(SpecHandle, GameplayTags.Damage, 25.f);
Projectile->DamageEffectSpecHandle = SpecHandle;
Projectile->FinishSpawning(SpawnTransform);
}
}Set By Caller로 설정 후, Set By Caller Magnitude의 DataTag를 설정해주면 된다.```cpp
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Damage")
FScalableFloat Damage;
const float ScaledDamage = Damage.GetValueAtLevel(GetAbilityLevel());
```