Hi All,
I’m trying to implement a Life Steal Gameplay Effect Exec Class. In this I need to modify the Attributes of Source as well as Target. My problem is that the attribute of Target is changed correctly, however, the attribute of Source does not change. Although both the attributes are captured properly but the changes only apply to Target and not the source.
My code:
GEExecLifeSteal.h
#pragma once
#include "CoreMinimal.h"
#include "GameplayEffectExecutionCalculation.h"
#include "GEExecLifeSteal.generated.h"
/**
*
*/
UCLASS()
class GASREP_API UGEExecLifeSteal : public UGameplayEffectExecutionCalculation
{
GENERATED_BODY()
public:
UGEExecLifeSteal();
void Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecParams, FGameplayEffectCustomExecutionOutput& ExecOutputs) const;
};
AND
GEExecLifeSteal.cpp
#include "GEExecLifeSteal.h"
#include "GASAttributeSet.h"
#include "AbilitySystemComponent.h"
struct SourceHealthCapture
{
DECLARE_ATTRIBUTE_CAPTUREDEF(Health)
SourceHealthCapture()
{
DEFINE_ATTRIBUTE_CAPTUREDEF(UGASAttributeSet, Health, Source, true)
}
};
struct TargetHealthCapture
{
DECLARE_ATTRIBUTE_CAPTUREDEF(Health)
TargetHealthCapture()
{
DEFINE_ATTRIBUTE_CAPTUREDEF(UGASAttributeSet, Health, Target, true)
}
};
static SourceHealthCapture& GetSourceHealthCapture()
{
static SourceHealthCapture SourceHealthCaptureVar;
return SourceHealthCaptureVar;
}
static TargetHealthCapture& GetTargetHealthCapture()
{
static TargetHealthCapture TargetHealthCaptureVar;
return TargetHealthCaptureVar;
}
UGEExecLifeSteal::UGEExecLifeSteal()
{
RelevantAttributesToCapture.Add(GetSourceHealthCapture().HealthDef);
RelevantAttributesToCapture.Add(GetTargetHealthCapture().HealthDef);
//Remember to add this tag to your project
ValidTransientAggregatorIdentifiers.AddTag(FGameplayTag::RequestGameplayTag("char.calc.damage.extra"));
}
void UGEExecLifeSteal::Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecParams, FGameplayEffectCustomExecutionOutput& ExecOutputs) const
{
//Get ASC
UAbilitySystemComponent* TargetAbilitySystemComponent = ExecParams.GetTargetAbilitySystemComponent();
UAbilitySystemComponent* SourceAbilitySystemComponent = ExecParams.GetSourceAbilitySystemComponent();
//Calc Variables for outputting final values
float OutSourceHealth = 0.0f;
float OutTargetHealth = 0.0f;
//Variables to store captured values
float SourceHealthMagnitude = 0.0f;
float TargetHealthMagnitude = 0.0f;
float ExtraAttackDamage = 0.0f;
ExecParams.AttemptCalculateCapturedAttributeMagnitude(GetSourceHealthCapture().HealthDef, FAggregatorEvaluateParameters(), SourceHealthMagnitude);
ExecParams.AttemptCalculateCapturedAttributeMagnitude(GetTargetHealthCapture().HealthDef, FAggregatorEvaluateParameters(), TargetHealthMagnitude);
ExecParams.AttemptCalculateTransientAggregatorMagnitude(FGameplayTag::RequestGameplayTag("char.calc.damage.extra"), FAggregatorEvaluateParameters(), ExtraAttackDamage);
//Start the Calculation
OutSourceHealth = SourceHealthMagnitude + (ExtraAttackDamage * 0.5);
OutTargetHealth = TargetHealthMagnitude - ExtraAttackDamage;
FString TargetActorLabel = TargetAbilitySystemComponent->GetOwnerActor()->GetActorLabel();
FString SourceActorLabel = SourceAbilitySystemComponent->GetOwnerActor()->GetActorLabel();
ExecOutputs.AddOutputModifier(FGameplayModifierEvaluatedData(GetSourceHealthCapture().HealthProperty, EGameplayModOp::Override, OutSourceHealth));
ExecOutputs.AddOutputModifier(FGameplayModifierEvaluatedData(GetTargetHealthCapture().HealthProperty, EGameplayModOp::Override, OutTargetHealth));
UE_LOG(LogTemp, Warning, TEXT("TA=%s, SA=%s, OutSourceHealth=%f, SourceHealthMagnitude=%f, OutTargetHealth=%f, TargetHealthMagnitude=%f"),
*TargetActorLabel, *SourceActorLabel, OutSourceHealth, SourceHealthMagnitude, OutTargetHealth, TargetHealthMagnitude);
}