Mini

[UE5] 실행 계산 개념, 아머속성 계산-변경 구현 본문

UE5/Damage

[UE5] 실행 계산 개념, 아머속성 계산-변경 구현

Mini_96 2024. 6. 23. 22:54

속성을 캡쳐할수있는 기능임

 

 

* 실행계산 구현

c++ 만들기

 

함수살펴보기, 구조체안에 많은기능이 있음

- 아바타액터얻기, 스펙 얻어보기

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);
}

 

이제우리는 계산된 데미지를 사용해야함
이제우리는 Modifier대신 Execution을 사용할거임

- Test

11.25
Add 모드이므로 11.25 + 11.25 가 된모습

Armor속성이 정상적으로 변경되고있음을 확인.

 

https://github.com/DongHoonYu96/GameplayAbilitySystem_Aura/commit/4478d5d539392372ceeb2e5ead3a6fdc23854dc6

 

feat : 아머속성 계산-변경 구현 · DongHoonYu96/GameplayAbilitySystem_Aura@4478d5d

Bisu96 committed Jun 23, 2024

github.com

 

'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