Questions on PostGameplayEffectExecute & ApplyGameplayEffectToTarget

Hi guys,

I am new to UE4, and I am learning the ability system right now, using c++.

I got stuck now, I want to apply a gameplay effect of health damage to the attribute set of the enemy. However, I am unable to do that, I think there is something wrong with my code in either ApplyGameplayEffectToTarget / PostGameplayEffectExecute, but I am really not sure.

Please help me guys!


#include "MeleeAbility.h"
#include "Abilities/Tasks/AbilityTask_PlayMontageAndWait.h"
#include "Abilities/GameplayAbility_Montage.h"
#include "Abilities/Tasks/AbilityTask_WaitGameplayEvent.h"
#include "GameplayTagsManager.h"
#include "AbilitySystemBlueprintLibrary.h"
#include "Enemy.h"

void UMeleeAbility::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);

AbilityHandle = Handle;
AbilityActorInfo = ActorInfo;
AbilityActivationInfo = ActivationInfo;

CommitAbility(Handle, ActorInfo, ActivationInfo);

if (CombatMontage)
{
int32 Skill = FMath::RandRange(0, 2);

switch (Skill)
{
case 0:
SkillSet = "Attack_1";
break;
case 1:
SkillSet = "Attack_2";
break;
case 2:
SkillSet = "Attack_3";
break;
default:
;
}

// Play the combat montage
UAbilityTask_PlayMontageAndWait* MontageProxy = UAbilityTask_PlayMontageAndWait::CreatePlayMontageAndWaitProxy(this, "None", CombatMontage, 1.f, SkillSet);
MontageProxy->Activate();

MontageProxy->OnCompleted.AddDynamic(this, &UMeleeAbility::AbilityFinish);
MontageProxy->OnBlendOut.AddDynamic(this, &UMeleeAbility::AbilityFinish);
MontageProxy->OnInterrupted.AddDynamic(this, &UMeleeAbility::AbilityFinish);
MontageProxy->OnCancelled.AddDynamic(this, &UMeleeAbility::AbilityFinish);
}

// Listen to the specific gameplay event
FGameplayTag DamageTag = UGameplayTagsManager::Get().RequestGameplayTag(TEXT("skill.melee.DealDamage"));

UAbilityTask_WaitGameplayEvent* DamageEvent = UAbilityTask_WaitGameplayEvent::WaitGameplayEvent(this, DamageTag);

DamageEvent->EventReceived.AddDynamic(this, &UMeleeAbility::AbilityDamage);
DamageEvent->Activate();
}

void UMeleeAbility::AbilityDamage(FGameplayEventData Payload)
{
AActor* EnemyTarget = const_cast<AActor*>(Payload.Target);

FGameplayAbilityTargetDataHandle Target = UAbilitySystemBlueprintLibrary::AbilityTargetDataFromActor(EnemyTarget);

if (DamageEffect)
{
ApplyGameplayEffectToTarget(AbilityHandle, AbilityActorInfo, AbilityActivationInfo, Target, DamageEffect, 1.f);
}
}


#include "CharacterBaseAttributeSet.h"
#include "GameplayEffectExtension.h"
#include "GameplayEffectTypes.h"

UCharacterBaseAttributeSet::UCharacterBaseAttributeSet()
:Health(200.f)
{

}

void UCharacterBaseAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
Super::PostGameplayEffectExecute(Data);

if (Data.EvaluatedData.Attribute.GetUProperty() == FindFieldChecked<UProperty>(UCharacterBaseAttributeSet::StaticClass(), GET_MEMBER_NAME_CHECKED(UCharacterBaseAttributeSet, Health)))
{
UE_LOG(LogTemp, Warning, TEXT("My health now is: %f"), Health.GetCurrentValue());
}

UE_LOG(LogTemp, Warning, TEXT("TESTING"));
}

It is highly recommended that you view this project:
tranek/GASDocumentation: My understanding of Unreal Engine 4’s GameplayAbilitySystem plugin with a simple multiplayer sample project. (github.com)

Were you able to solve this? I’m experiencing similar issues where the attribute manipulation just doesn’t want to happen when using ApplyGameplayEffectToTarget.

Solve this by replacing UProperty with FProperty like this:

	auto Property = FindFieldChecked<FProperty>(UAttributeSetBase::StaticClass(),
		GET_MEMBER_NAME_CHECKED(UAttributeSetBase, Health));
	auto Property2 = Data.EvaluatedData.Attribute.GetUProperty();

	if (Property == Property2)
	{
		UE_LOG(LogTemp, Warning, TEXT("Health: %f"), Health.GetCurrentValue());
	}