Hi, I am programming my game (in projects called “Attrition”) using the gameplay ability system (GAS for short). I am creating a damage volume where if you enter you lose 10 of heath per second, but i am running into a problem while creating the Gameplay Effect Execution Calculation class. This is the full code:
// Fill out your copyright notice in the Description page of Project Settings.
#include "Character/Abilities/AttritionDamageCalculation.h"
#include "Character/Abilities/Attributes/HealthSet.h"
#include "Character/Abilities/AttritionAbilitySystemComponent.h"
struct FDamageStatics
{
DECLARE_ATTRIBUTE_CAPTUREDEF(Damage);
DECLARE_ATTRIBUTE_CAPTUREDEF(Health);
FDamageStatics()
{
DEFINE_ATTRIBUTE_CAPTUREDEF(UHealthSet, Damage, Source, true);
DEFINE_ATTRIBUTE_CAPTUREDEF(UHealthSet, Health, Target, false);
}
};
static const FDamageStatics& DamageStatics()
{
static FDamageStatics DStatics;
return DStatics;
}
UAttritionDamageCalculation::UAttritionDamageCalculation()
{
RelevantAttributesToCapture.Add(DamageStatics().DamageDef);
RelevantAttributesToCapture.Add(DamageStatics().HealthDef);
}
void UAttritionDamageCalculation::Execute_Implementation(
const FGameplayEffectCustomExecutionParameters& ExecutionParams,
OUT FGameplayEffectCustomExecutionOutput& OutExecutionOutput) const
{
UAbilitySystemComponent* TargetAbilitySystemComponent = ExecutionParams.GetTargetAbilitySystemComponent();
UAbilitySystemComponent* SourceAbilitySystemComponent = ExecutionParams.GetSourceAbilitySystemComponent();
AActor* SourceActor = SourceAbilitySystemComponent ? SourceAbilitySystemComponent->GetAvatarActor() : nullptr;
AActor* TargetActor = TargetAbilitySystemComponent ? TargetAbilitySystemComponent->GetAvatarActor() : nullptr;
const FGameplayEffectSpec& Spec = ExecutionParams.GetOwningSpec();
// Gather the tags from the source and target as that can affect which buffs should be used
const FGameplayTagContainer* SourceTags = Spec.CapturedSourceTags.GetAggregatedTags();
const FGameplayTagContainer* TargetTags = Spec.CapturedTargetTags.GetAggregatedTags();
FAggregatorEvaluateParameters EvaluationParameters;
EvaluationParameters.SourceTags = SourceTags;
EvaluationParameters.TargetTags = TargetTags;
float Damage = 0.0f;
// Capture optional damage value set on the damage GE as a CalculationModifier under the ExecutionCalculation
ExecutionParams.AttemptCalculateCapturedAttributeMagnitude(DamageStatics().DamageDef, EvaluationParameters, Damage);
// Add SetByCaller damage if it exists
Damage += FMath::Max<float>(Spec.GetSetByCallerMagnitude(FGameplayTag::RequestGameplayTag(FName("Event.Damage")), false, -1.0f), 0.0f);
//Here should be any extra handling of various buffs/debuffs (Armor, for example)
const float MitigatedDamage = Damage;
if (MitigatedDamage > 0.f)
{
UE_LOG(LogTemp, Log, TEXT("Damage is %f"), MitigatedDamage)
if(DamageStatics().HealthProperty != nullptr)
OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(DamageStatics().HealthProperty, EGameplayModOp::Additive, -MitigatedDamage));
else
{
UE_LOG(LogTemp, Error, TEXT("The health property is NULL in function %s()! This will crash the engine. Now keeping the value of damage in the damage attribute."), *FString(__FUNCTION__))
OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(DamageStatics().DamageProperty, EGameplayModOp::Additive, MitigatedDamage));
}
}
}
the problem is, this line:
if(DamageStatics().HealthProperty != nullptr)
OutExecutionOutput.AddOutputModifier(FGameplayModifierEvaluatedData(DamageStatics().HealthProperty, EGameplayModOp::Additive, -MitigatedDamage));
crashes the engine, with this error
Unhandled Exception: EXCEPTION_ACCESS_VIOLATION reading address 0xffffffffffffffff (In line 70, the one with AddOutputModifier)
even if i checked that HealthProperty isn’t nullptr and have an else statement.
I am welcome to help of any kind, but i would prefer to just subtract damage from health since i don’t quite already know how to implement correctly a damage attribute that keeps the value of damage, but if you know how, please leave a comment!
Thanks for your time.