Reflection Ability
Created By: Ikthaleon
In our game we have the concept of casting a "reflection" ability. This ability lasts for a few seconds and causes a set amount of damage to the attacker each time they hit the caster.
To do this, we set a Gameplay Effect on the casting character, and each time they are attacked, we check to see if the Gameplay Effect is there, and if so to damage to the attacker.
/* This is where the effect is called (we call it from within the GameplayAbility itself). For context this is called from our PreGameplayEffectExecute - we process damage and healing effects here. */ ApplyReflect(FName(TEXT("GE_ReflectShield")), Data, attackingCharacter, receiverCharacter);
/* Apply the Reflect effect on the attackingCharacter (that is the caster). Having this effect for the lifetime of the effect means that whenever the attackingCharacter is hit, we check for the reflection, and cause damage back to the attacker. The attackingCharacter has a GameplayEffect ability called "BaneShieldReflect" in BP (allowing different reflection choices for the designer). */ void UAttributeSetBase::ApplyReflect(FName reflectTagName, struct FGameplayEffectModCallbackData &Data, ACharacterBase* attackingCharacter, ACharacterBase* receiverCharacter) { if ((receiverCharacter) && (attackingCharacter)) { /* Cause Effect on the Attacker */ UGameplayEffect* effect = NewObject<UGameplayEffect>(GetTransientPackage(), reflectTagName); if (effect)It { FGameplayEffectSpecHandle geReflect = attackingCharacter->GetAbilitySystemComponent()->MakeOutgoingSpec( attackingCharacter->BaneShieldReflect, 1, attackingCharacter->GetAbilitySystemComponent()->MakeEffectContext()); attackingCharacter->GetAbilitySystemComponent()->ApplyGameplayEffectSpecToSelf(*geReflect.Data.Get()); UE_LOG(LogAttributes, Warning, TEXT("Applying Reflect effect to %s"), *attackingCharacter->CharacterName); } else { UE_LOG(LogAttributes, Warning, TEXT("Reflect effect not found")); } } else { UE_LOG(LogAttributes, Warning, TEXT("receiverCharacter / attackingCharacter not found")); } }
/* Determine if Reflect shield is active Params : receiverCharacter - character that is being inspected tagName - tag on the receiverCharacter that indicates the reflect shield is active */ bool UAttributeSetBase::IsReflectShieldActive(ACharacterBase* receiverCharacter, FName tagName) { FGameplayTag ReflectShieldTag = UGameplayTagsManager::Get().RequestGameplayTag(tagName, false); // If we get nothing back from the UGameplayTagsManager indicates the shield is not active if (ReflectShieldTag.EmptyTag == ReflectShieldTag) { UE_LOG(LogAttributes, Warning, TEXT("Reflect Shield Tag not present")); return false; } // Logging for debugging :) If the receiverCharacter has the reflect shield tag, log all their tags if (receiverCharacter && receiverCharacter->GetAbilitySystemComponent()->HasAllMatchingGameplayTags(FGameplayTagContainer(ReflectShieldTag))) { receiverCharacter->LogOwnedTags(); UE_LOG(LogAttributes, Warning, TEXT("Reflect Shield is active for %s"), *receiverCharacter->CharacterName); return true; } return false; }
// Display list of currently owned tags for this actor void ACharacterBase::LogOwnedTags() { TArray<FGameplayTag> tagArray; FGameplayTagContainer OwnerTags; OwnerTags.Reset(); GetAbilitySystemComponent()->GetOwnedGameplayTags(OwnerTags); OwnerTags.GetGameplayTagArray(tagArray); for (FGameplayTag gameTag : tagArray) { UE_LOG(LogAttributes, Warning, TEXT("[%s] has tag : %s"), *CharacterName, *gameTag.GetTagName().ToString()); } }