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