속성을 캡쳐할수있는 기능임
* 실행계산 구현
- 아바타액터얻기, 스펙 얻어보기
UExecCalc_Damage::UExecCalc_Damage()
{
}
void UExecCalc_Damage::Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecutionParams,
FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const
{
const UAbilitySystemComponent* SourceASC= ExecutionParams.GetSourceAbilitySystemComponent();
const UAbilitySystemComponent* TargetASC= ExecutionParams.GetTargetAbilitySystemComponent();
//ASC가 유효한경우만 avataractor 얻기
const AActor* SourceAvatar = SourceASC ? SourceASC->GetAvatarActor() : nullptr;
const AActor* TargetAvatar = TargetASC ? TargetASC->GetAvatarActor() : nullptr;
const FGameplayEffectSpec& Spec = ExecutionParams.GetOwningSpec();
}
- 속성캡쳐하는 방법
이전에 mmc에서 어떻게 했는지 살펴보자
캡쳐구조체변수를선언하고, 생성자에서 값을 넣어줬었음.
UCLASS()
class AURA_API UMMC_MaxHealth : public UGameplayModMagnitudeCalculation
{
GENERATED_BODY()
public:
UMMC_MaxHealth();
virtual float CalculateBaseMagnitude_Implementation(const FGameplayEffectSpec& Spec) const override;
private:
FGameplayEffectAttributeCaptureDefinition VigorDef;
};
// Fill out your copyright notice in the Description page of Project Settings.
#include "AbilitySystem/ModMagCalc/MMC_MaxHealth.h"
#include "AbilitySystem/AuraAttributeSet.h"
#include "Interaction/CombatInterface.h"
//캡쳐정의의 매개변수설정
UMMC_MaxHealth::UMMC_MaxHealth()
{
//VigorDef 채우기
VigorDef.AttributeToCapture = UAuraAttributeSet::GetVigorAttribute(); //AS클래스에서 getter매크로 사용
VigorDef.AttributeSource=EGameplayEffectAttributeCaptureSource::Target; //타겟vs소스
VigorDef.bSnapshot = false; //타이밍
RelevantAttributesToCapture.Add(VigorDef); //관련속성에 추가하여 캡쳐
}
float UMMC_MaxHealth::CalculateBaseMagnitude_Implementation(const FGameplayEffectSpec& Spec) const
{
//gather tags from source and target
const FGameplayTagContainer* SourceTags = Spec.CapturedSourceTags.GetAggregatedTags();
const FGameplayTagContainer* TargetTags = Spec.CapturedTargetTags.GetAggregatedTags();
FAggregatorEvaluateParameters EvaluateParameters;
EvaluateParameters.TargetTags = TargetTags;
EvaluateParameters.SourceTags = SourceTags;
//* vigor과 level을 얻은후, 계산해서 리턴하면됨
float Vigor=0.f;
GetCapturedAttributeMagnitude(VigorDef,Spec,EvaluateParameters,Vigor); //Vigor에 Vigor값 넣어줘
Vigor=FMath::Max<float>(Vigor,0.f);
ICombatInterface* CombatInterface = Cast<ICombatInterface>(Spec.GetContext().GetSourceObject());
const int32 PlayerLevel = CombatInterface->GetPlayerLevel();
return 80.f+2.5f*Vigor+10.f*PlayerLevel;
}
- 구현(아머속성캡쳐 하고 수정)
//BP에노출안할거임, c++안에서만 사용되는 원시구조체
struct AuraDamageStatics
{
//캡쳐속성 선언 매크로 : 속성포인터가지고있음
DECLARE_ATTRIBUTE_CAPTUREDEF(Armor);
AuraDamageStatics()
{
DEFINE_ATTRIBUTE_CAPTUREDEF(UAuraAttributeSet, Armor, Target, false); //아머라는 속성을 캡쳐하겠다.
}
};
//싱글톤 Getter
static const AuraDamageStatics& DamageStatics()
{
static AuraDamageStatics Dstatics;
return Dstatics;
}
UExecCalc_Damage::UExecCalc_Damage()
{
RelevantAttributesToCapture.Add(DamageStatics().ArmorDef); //캡쳐속성 배열에추가
}
void UExecCalc_Damage::Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecutionParams,
FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const
{
const UAbilitySystemComponent* SourceASC= ExecutionParams.GetSourceAbilitySystemComponent();
const UAbilitySystemComponent* TargetASC= ExecutionParams.GetTargetAbilitySystemComponent();
//ASC가 유효한경우만 avataractor 얻기
const AActor* SourceAvatar = SourceASC ? SourceASC->GetAvatarActor() : nullptr;
const AActor* TargetAvatar = TargetASC ? TargetASC->GetAvatarActor() : nullptr;
const FGameplayEffectSpec& Spec = ExecutionParams.GetOwningSpec();
const FGameplayTagContainer* SourceTags = Spec.CapturedSourceTags.GetAggregatedTags();
const FGameplayTagContainer* TargetTags = Spec.CapturedTargetTags.GetAggregatedTags();
FAggregatorEvaluateParameters EvaluateParameters;
EvaluateParameters.SourceTags = SourceTags;
EvaluateParameters.TargetTags = TargetTags;
float Armor=0.f;
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(DamageStatics().ArmorDef,EvaluateParameters,Armor);
Armor=FMath::Max<float>(0.f,Armor);
++Armor; //Test용
//실제속성변경
const FGameplayModifierEvaluatedData EvaluatedData(DamageStatics().ArmorProperty, EGameplayModOp::Additive, Armor);
OutExecutionOutput.AddOutputModifier(EvaluatedData);
}
- Test
Armor속성이 정상적으로 변경되고있음을 확인.
'UE5 > Damage' 카테고리의 다른 글
[UE5] 방어력, 방관 구현 (0) | 2024.06.24 |
---|---|
[UE5] Block Chance 구현 (0) | 2024.06.23 |
[UE5] 맞은적 머리위에 데미지 뜨도록 구현 (0) | 2024.06.23 |
[UE5] 적 죽을때 용해효과 구현 (0) | 2024.06.23 |
[UE5] 적 죽음 구현 (0) | 2024.06.23 |