* execcalc에서 캡쳐속성선언
//BP에노출안할거임, c++안에서만 사용되는 원시구조체
struct AuraDamageStatics
{
//캡쳐속성 선언 매크로 : 속성포인터가지고있음
...
DECLARE_ATTRIBUTE_CAPTUREDEF(FireResistance);
DECLARE_ATTRIBUTE_CAPTUREDEF(LightningResistance);
DECLARE_ATTRIBUTE_CAPTUREDEF(ArcaneResistance);
DECLARE_ATTRIBUTE_CAPTUREDEF(PhysicalResistance);
* 속성캡쳐 from target(고블린)
AuraDamageStatics()
{
..
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, FireResistance, Target, false); //아머라는 속성을 캡쳐하겠다. from 공격자(아우라)임에 주의
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, LightningResistance, Target, false); //아머라는 속성을 캡쳐하겠다. from 공격자(아우라)임에 주의
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, ArcaneResistance, Target, false); //아머라는 속성을 캡쳐하겠다. from 공격자(아우라)임에 주의
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, PhysicalResistance, Target, false); //아머라는 속성을 캡쳐하겠다. from 공격자(아우라)임에 주의
}
* 속성캡쳐 배열에 추가
UExecCalc_Damage::UExecCalc_Damage()
{
...
RelevantAttributesToCapture.Add(DamageStatics().FireResistanceDef); //캡쳐속성 배열에추가
RelevantAttributesToCapture.Add(DamageStatics().LightningResistanceDef); //캡쳐속성 배열에추가
RelevantAttributesToCapture.Add(DamageStatics().ArcaneResistanceDef); //캡쳐속성 배열에추가
RelevantAttributesToCapture.Add(DamageStatics().PhysicalResistanceDef); //캡쳐속성 배열에추가
}
* 태그 : 속성 매칭용 map 만들고 값넣기
TMap<FGameplayTag,FGameplayEffectAttributeCaptureDefinition> TagsToCaptureDefs; //tag와 속성연결
AuraDamageStatics()
{
...
const FAuraGameplayTags& Tags = FAuraGameplayTags::Get();
TagsToCaptureDefs.Add(Tags.Attributes_Secondary_Armor, ArmorDef);
TagsToCaptureDefs.Add(Tags.Attributes_Secondary_BlockChance, BlockChanceDef);
TagsToCaptureDefs.Add(Tags.Attributes_Secondary_ArmorPenetration, ArmorPenetrationDef);
TagsToCaptureDefs.Add(Tags.Attributes_Secondary_CriticalHitChance, CriticalHitChanceDef);
TagsToCaptureDefs.Add(Tags.Attributes_Secondary_CriticalHitResistance, CriticalHitResistanceDef);
TagsToCaptureDefs.Add(Tags.Attributes_Secondary_CriticalHitDamage, CriticalHitDamageDef);
TagsToCaptureDefs.Add(Tags.Attributes_Resistance_Arcane, ArcaneResistanceDef);
TagsToCaptureDefs.Add(Tags.Attributes_Resistance_Fire, FireResistanceDef);
TagsToCaptureDefs.Add(Tags.Attributes_Resistance_Lightning, LightningResistanceDef);
TagsToCaptureDefs.Add(Tags.Attributes_Resistance_Physical, PhysicalResistanceDef);
}
};
** 이전강의 누락분
* 데미지태그, 맵<데미지타입 : 저항타입> 추가
struct FAuraGameplayTags
{
public:
...
FGameplayTag Damage;
FGameplayTag Damage_Fire;
FGameplayTag Damage_Lightning;
FGameplayTag Damage_Arcane;
FGameplayTag Damage_Physical;
// TArray<FGameplayTag> DamageTypes;
TMap<FGameplayTag, FGameplayTag> DamageTypesToResistances;
* 게임태그 초기화(데미지타입, 저항타입) && 맵에 추가
/*
* Damage Types
*/
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")
);
/*
* 방마저 Attributes
*/
GameplayTags.Attributes_Resistance_Arcane = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Attributes.Resistance.Arcane"),
FString("Arcane Resistance")
);
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_Physical = UGameplayTagsManager::Get().AddNativeGameplayTag(
FName("Attributes.Resistance.Physical"),
FString("Physical Resistance")
);
/*
* Map of Damage Types to Resistances
*/
GameplayTags.DamageTypesToResistances.Add(GameplayTags.Damage_Arcane, GameplayTags.Attributes_Resistance_Arcane);
GameplayTags.DamageTypesToResistances.Add(GameplayTags.Damage_Lightning, GameplayTags.Attributes_Resistance_Lightning);
GameplayTags.DamageTypesToResistances.Add(GameplayTags.Damage_Physical, GameplayTags.Attributes_Resistance_Physical);
GameplayTags.DamageTypesToResistances.Add(GameplayTags.Damage_Fire, GameplayTags.Attributes_Resistance_Fire);
** 이어서
* 저항값을 가져와서 %로 데미지 감소구현
float Damage = 0.f;
for (const TTuple<FGameplayTag, FGameplayTag>& Pair : FAuraGameplayTags::Get().DamageTypesToResistances)
{
//map < 데미지타입, 저항속성>
const FGameplayTag DamageType = Pair.Key;
const FGameplayTag ResistanceTag = Pair.Value;
//저항속성이 TagsToCaptureDefs맵에 없는경우 예외처리, 에러시메시지
checkf(AuraDamageStatics().TagsToCaptureDefs.Contains(ResistanceTag), TEXT("TagsToCaptureDefs doesn`t contain Tag: [%s] in ExceCalc_Damage"),
*ResistanceTag.ToString());
//저항태그 에 대항하는 데미지캡쳐
const FGameplayEffectAttributeCaptureDefinition CaptureDef = AuraDamageStatics().TagsToCaptureDefs[ResistanceTag];
float DamageTypeValue = Spec.GetSetByCallerMagnitude(DamageType);
float Resistance = 0.f;
//캡쳐된 속성값 계산
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(CaptureDef, EvaluationParameters, Resistance);
//감소율은 0~100으로 제한
Resistance = FMath::Clamp(Resistance,0.f,100.f);
DamageTypeValue *= (100.f - Resistance) / 100.f; //저항%만큼 데미지 감소시키기
Damage += DamageTypeValue;
}
'UE5 > Advance Damage Techniques' 카테고리의 다른 글
[UE5] Advanced Damage 기술 퀴즈 (0) | 2024.08.22 |
---|---|
[UE5] 멀티플레이 test // 서버 트러블슈팅 클라에서 데미지 표시안됨 해결, 각자 클라에서는 각자의 데미지만 표시 구현 (0) | 2024.08.22 |
[UE5] 방마저 속성추가 / 리플리케이션 / 속성위젯에 속성추가 (0) | 2024.08.18 |
[UE5] 데미지 유형들 추가, 확장성 refactor (0) | 2024.08.15 |
[UE5] 크리시 글자 애니메이션 구현, 메시지 구현, 인스턴싱 정책 (0) | 2024.08.14 |