1. 속성 저항 태그 생성 및 데미지 계산식 수정
(1) AuraGameplayTags - Native 게임플레이 태그 생성
속성 저항을 도입하기 위해 새로운 태그를 생성한다.
새로운 속성 타입을 생성한다.
FGameplayTag Attributes_Resistance_Fire;
FGameplayTag Attributes_Resistance_Arcane;
FGameplayTag Attributes_Resistance_Lightning;
FGameplayTag Attributes_Resistance_Physical;
// 데미지
FGameplayTag Damage;
FGameplayTag Damage_Fire;
FGameplayTag Damage_Lightning;
FGameplayTag Damage_Arcane;
FGameplayTag Damage_Physical;
TMap<FGameplayTag, FGameplayTag> DamageTypesToResistances;
// 데미지 타입
GameplayTags.Damage_Fire = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Damage.Fire"),
FString("Fire Damage Type")
);
GameplayTags.Damage_Lightning = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Damage.Lightning"),
FString("Lightning Damage Type")
);
GameplayTags.Damage_Arcane = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Damage.Arcane"),
FString("Arcane Damage Type")
);
GameplayTags.Damage_Physical = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Damage.Physical"),
FString("Physical Damage Type")
);
// 저항
GameplayTags.Attributes_Resistance_Fire = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Attributes.Resistance.Fire"),
FString("Fire Resistance")
);
GameplayTags.Attributes_Resistance_Lightning = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Attributes.Resistance.Lightning"),
FString("Lightning Resistance")
);
GameplayTags.Attributes_Resistance_Arcane = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Attributes.Resistance.Arcane"),
FString("Arcane Resistance")
);
GameplayTags.Attributes_Resistance_Physical = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Attributes.Resistance.Physical"),
FString("Physical Resistance")
);
// 데미지 타입과 저항 연결
GameplayTags.DamageTypesToResistances.Add(GameplayTags.Damage_Fire, GameplayTags.Attributes_Resistance_Fire);
GameplayTags.DamageTypesToResistances.Add(GameplayTags.Damage_Lightning, GameplayTags.Attributes_Resistance_Lightning);
GameplayTags.DamageTypesToResistances.Add(GameplayTags.Damage_Arcane, GameplayTags.Attributes_Resistance_Arcane);
GameplayTags.DamageTypesToResistances.Add(GameplayTags.Damage_Physical, GameplayTags.Attributes_Resistance_Physical);
기존의 Array를 대체하여 각 속성 타입에 대해 속성 저항을 값으로 갖는 TMap을 갖게 될것이다.
(2) ExecCalc_Damage - 데미지 계산식 수정
// Set by Caller Magnitude 가져오기
float Damage = 0.f;
for (auto& Pair : FAuraGameplayTags::Get().DamageTypesToResistances)
{
const float DamageTypeValue = Spec.GetSetByCallerMagnitude(Pair.Key);
Damage += DamageTypeValue;
}
2. AuraAttributeSet 속성 세트에 속성으로 추가하기
이전까지의 작업은 속성 저항에 대한 데미지 계산과 Native 게임플레이 태그 생성이다.
이제 속성으로 추가한다.
(1) 헤더 파일
/*
* Secondary 속성 - 속성 저항
*/
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_FireResistance, Category = "Resistances Attributes")
FGameplayAttributeData FireResistance;
ATTRIBUTE_ACCESSORS(UAuraAttributeSet, FireResistance);
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_LightningResistance, Category = "Resistances Attributes")
FGameplayAttributeData LightningResistance;
ATTRIBUTE_ACCESSORS(UAuraAttributeSet, LightningResistance);
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_ArcaneResistance, Category = "Resistances Attributes")
FGameplayAttributeData ArcaneResistance;
ATTRIBUTE_ACCESSORS(UAuraAttributeSet, ArcaneResistance);
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_PhysicalResistance, Category = "Resistances Attributes")
FGameplayAttributeData PhysicalResistance;
ATTRIBUTE_ACCESSORS(UAuraAttributeSet, PhysicalResistance);
각 저항에 대한 Getter, Setter를 선언하는 매크로를 추가하고 블루프린트에서 불러들일 수 있도록 속성 데이터를 생성한다.
그리고 ReplicatedUsing 인수를 사용하여 복제가 발생하면 해당 함수를 호출하도록 지정한다.
UFUNCTION()
void OnRep_FireResistance(const FGameplayAttributeData& OldFireResistance) const;
UFUNCTION()
void OnRep_LightningResistance(const FGameplayAttributeData& OldLightningResistance) const;
UFUNCTION()
void OnRep_ArcaneResistance(const FGameplayAttributeData& OldArcaneResistance) const;
UFUNCTION()
void OnRep_PhysicalResistance(const FGameplayAttributeData& OldPhysicalResistance) const;
(2) 생성자
UAuraAttributeSet::UAuraAttributeSet()
{
const FAuraGameplayTags& GameplayTags = FAuraGameplayTags::Get();
// 주 속성
TagsToAttributes.Add(GameplayTags.Attributes_Primary_Strength, GetStrengthAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Primary_Intelligence, GetIntelligenceAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Primary_Resilience, GetResilienceAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Primary_Vigor, GetVigorAttribute);
// 2차 속성
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_Armor, GetArmorAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_ArmorPanetration, GetArmorPenetrationAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_BlockChance, GetBlockChanceAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_CriticalHitChance, GetCriticalHitChanceAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_CriticalHitDamage, GetCriticalHitDamageAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_CriticalHitResistance, GetCriticalHitResistanceAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_HealthRegeneration, GetHealthRegenerationAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_ManaRegeneration, GetManaRegenerationAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_MaxHealth, GetMaxHealthAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Secondary_MaxMana, GetMaxManaAttribute);
// 속성 저항
TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Fire, GetFireResistanceAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Lightning, GetLightningResistanceAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Arcane, GetArcaneResistanceAttribute);
TagsToAttributes.Add(GameplayTags.Attributes_Resistance_Physical, GetPhysicalResistanceAttribute);
}
생성했던 Native 태그를 속성으로 추가할 것이다.
TMap<FGameplayTag, TStaticFuncPtr<FGameplayAttribute()>> TagsToAttributes;
위의 맵에 키-값 쌍이 태그-함수 포인터 쌍으로 되도록 지정한다.
(3) GetLifeTimeReplicatedProps 함수
// 속성 저항
DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, FireResistance, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, LightningResistance, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, ArcaneResistance, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UAuraAttributeSet, PhysicalResistance, COND_None, REPNOTIFY_Always);
}
새롭게 생성한 저항 속성들에 대해 복제가 항상 일어나도록 지정한다.
(4) 복제 발생 시 작동하는 콜백 함수
void UAuraAttributeSet::OnRep_FireResistance(const FGameplayAttributeData& OldFireResistance) const
{
// Notify 매크로
GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, FireResistance, OldFireResistance);
}
void UAuraAttributeSet::OnRep_LightningResistance(const FGameplayAttributeData& OldLightningResistance) const
{
// Notify 매크로
GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, LightningResistance, OldLightningResistance);
}
void UAuraAttributeSet::OnRep_ArcaneResistance(const FGameplayAttributeData& OldArcaneResistance) const
{
// Notify 매크로
GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, ArcaneResistance, OldArcaneResistance);
}
void UAuraAttributeSet::OnRep_PhysicalResistance(const FGameplayAttributeData& OldPhysicalResistance) const
{
// Notify 매크로
GAMEPLAYATTRIBUTE_REPNOTIFY(UAuraAttributeSet, PhysicalResistance, OldPhysicalResistance);
}
복제가 발생하여 각 속성 값이 변경되면 위의 함수가 발동되며, 속성 세트에 대해 값이 변경된다.
3. 속성 메뉴 위젯에 속성 저항 값 추가하기
(1) BP_AttributeMenuWidgetController - 속성 메뉴 위젯 컨트롤러
이 위젯 컨트롤러는 DA_AttributeInfo 데이터 에셋을 가지고 속성 값을 위젯으로 전송하고 있다.
(1-2) DA_AttributeInfo 데이터 에셋
이전에 추가한 속성 저항 Attributes에 대하여 값을 추가한다.
(2) WBP_AttributeMenu
속성 값을 가져와 표기할 줄을 추가한다.
해당 Row에 대해 변수로 사용을 체크한다.
Set Attribute Tags 함수에 대해서 각 행에 태그를 가져와 값을 설정하는 노드를 연결한다.
올바르게 연결되었다면 위처럼 나타날 것이다.
(3) GE_SecondaryAttributes 에 수정자 추가
이제 캐릭터에 속성 저항을 부여하기 위해 게임플레이 이펙트를 수정한다.
모든 속성 저항은 Resilience를 따라 설정되도록 한다.
'UE 5 스터디 > Gameplay Ability System(GAS)' 카테고리의 다른 글
12-10. 멀티플레이어 디버깅 (0) | 2024.12.27 |
---|---|
12-9. 데미지 타입 - (3) 속성 저항 데미지 계산 (0) | 2024.12.26 |
12-7. 데미지 타입 - (1) 게임플레이 태그와 게임플레이 어빌리티 생성 (0) | 2024.12.26 |
12-6. UI - (10) 블록, 크리티컬 메세지 띄우기 (0) | 2024.12.26 |
12-5. UI - (9) 색이 있는 데미지 텍스트 띄우기 (0) | 2024.12.26 |