I have two AttributeSet, one for the player class and another for enemy currently. Each AttributeSet has the Health attribute. I also use PostGameplayEffectExecute() to limit the scope of Health attribute in both AttributeSet. However, the player AttributeSet calling PostGameplayEffectExecute() succeeded, the enemy AttributeSet failed.
When playing the level in Engine, I get an error in the output log:
LogOutputDevice: Error: === Handled ensure: ===
LogOutputDevice: Error: Ensure condition failed: AbilityComp [File:E:\Unreal Projects\LostVisage\Source\LostVisage\EnemyAttributeSet.h] [Line: 31]
LogOutputDevice: Error: Stack:
LogOutputDevice: Error: [Callstack] 0x00007ffb062c84e8 UE4Editor-LostVisage-0007.dll!<lambda_aa91740606708f06f8509233f5471518>::operator()() [E:\Unreal Projects\LostVisage\Source\LostVisage\EnemyAttributeSet.h:31]
LogOutputDevice: Error: [Callstack] 0x00007ffb062b6721 UE4Editor-LostVisage-0007.dll!UEnemyAttributeSet::PostGameplayEffectExecute() [E:\Unreal Projects\LostVisage\Source\LostVisage\EnemyAttributeSet.cpp:39]
According to the message, I found the macro ATTRIBUTE_ACCESSORS() implements a set function, which calls GetOwningAbilitySystemComponent() and ensure():
FORCEINLINE void SetHealth(float NewVal)
{
UAbilitySystemComponent* AbilityComp = GetOwningAbilitySystemComponent();
if (ensure(AbilityComp))
{
AbilityComp->SetNumericAttributeBase(GetHealthAttribute(), NewVal);
};
}
Obviously, this code caused the bug. I have no idea why enemy AttributeSet can’t call GetOwningAbilitySystemComponent() successfully.
here is the my implements of GetOwningAbilitySystemComponent(), two AttributeSet have the same implements:
void UEnemyAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data)
{
Super::PostGameplayEffectExecute(Data);
UE_LOG(LogTemp, Warning, TEXT("Enter PostGameplayEffectExecute"));
if (Data.EvaluatedData.Attribute == GetHealthAttribute())
{
SetHealth(FMath::Clamp(GetHealth(), 0.0f, 100.0f));
UE_LOG(LogTemp, Warning, TEXT("Enter EvaluatedData"));
UE_LOG(LogTemp, Warning, TEXT("Health before: %f"), GetHealth());
//SetHealth(0.0f);
UE_LOG(LogTemp, Warning, TEXT("Health after: %f"), GetHealth());
}
}
And the melee attack ability to call this:
Thank you so much for your attention!