I am creating a Gameplay Effect for a “magic shield” has blocks things (projectiles, enemies, etc.).
This Gameplay Effect is meant to be applied by various Gameplay Abilities (e.g. “apply magic shield to self”, “apply magic shield to target”, “apply magic shield to all in party”…)
The actual effect is a “magic shield” Actor with a collision, that I want to spawn and attach to the target of the Gameplay Effect when it is applied, and despawn when it is removed.
I am not sure how to best achieve this.
There is UGameplayEffect::OnApplied() where I could put my spawning logic, but I cannot find an equivalent when a Gameplay Effect is removed.
I thought of using a Gameplay Cue but since this is gameplay-critical is seems like a poor choice.
I really want to compartmentalize the logic so that a GameplayEffect is self-contained and is able to run whatever logic it needs when applied and removed (in this particular case, spawning the magic shield Actor).
Here’s what I did:
UCLASS(Blueprintable)
class MY_API UScriptableGameplayEffect : public UGameplayEffect
{
GENERATED_BODY()
public:
/** Registers to receive GameplayEffect events */
static void RegisterForGameplayEffectEvents(UAbilitySystemComponent* ASC);
/** Called when this ScriptableGameplayEffect is applied to a target */
UFUNCTION(BlueprintImplementableEvent)
void OnApplied(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle, AActor* Target) const;
/** Called when this ScriptableGameplayEffect is removed from a target */
UFUNCTION(BlueprintImplementableEvent)
void OnRemoved(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle, AActor* Target) const;
};
Further research seem to suggest that a way to achieve my goal might be for the GameplayEffect to grant a GameplayAbility to the target, that auto-activates and handles whatever logic is required (e.g. spawning the magic shield Actor in my current use case).
I don’t understand the underlying systems of the Gameplay Ability System well enough to tell which is the best solution. Any feedback from someone who has some experience with the system would be welcome.
If anyone stumbles upon this thread and wants to know, further reading seemed to indicate that Gameplay Effects in GAS are intended to be data only. Gameplay logic should only exist in Gameplay Abilities, from what I gather.
Thus, the solution to have some logic being run when a Gameplay Effect is applied is indeed to set up a Grant Gameplay Abilities component:
For my specific use case, an auto-activated Gameplay Ability granted by the Gameplay Effect handles the spawning of the “magic shield” Actor, then uses the Wait For Gameplay Effect Removed ability task to know when the Gameplay Effect is removed and handle the destruction of the “magic shield” Actor.
I hope posting this final resolution helps someone in the future!