Description

When multiple duration GameplayEffects apply a GameplayCue with the same tag, the network authority game instance (standalone & servers) will remove all GameplayCues with that tag from the AbilitySystemComponent's FActiveGameplayCueContainer.

This affects executions of GameplayCueNotifies, as their OnRemove (5.5: OnCeaseRelevant) functions are executed too early, namely on the first cue expiring rather than on the individual cues expiring. The problem is caused by FActiveGameplayCueContainer::RemoveCue() matching multiple active cues to this check:

 

if (Cue.GameplayCueTag == Tag)

 

This problem seems to affect the server and standalone instances only, as clients that get their cue expirations triggered by replication will execute the GCN OnRemove with the correct timing. Still, this needs to be addressed so that GCNs work properly on servers and in standalone.

Steps to Reproduce
  • Create a GameplayEffect GE_ApplyCue with duration = 5s that applies GameplayCue with tag GameplayCue.MyTestCue
  • Create a GameplayCueNotify_Actor GCN_DurationCue that implements WhileActive (5.5: OnBecomeRelevant) to print a message "Start!" and implements OnRemove (5.5 OnCeaseRelevant) to print "Removed!".
  • Created a LocalPredicted GameplayAbility GA_ApplyCue that applies GE_ApplyCue to owner and ends ability immediately so it can be repeated.
  • Start PIE in standalone (so playing as auth):
    • Activate GA_ApplyCue once, wait 3 seconds, then activate it 4 more times.
    • Observe: The gameplay notify actor GCN_Duration will print it's "Removed!" message 5 times immediately after the first application of GE_ApplyCue expires.
    • Expected: The gameplay notify actor GCN_Duration prints it's "Removed!" message exactly when each individual GameplayEffect expires, so 5 seconds after each activation.
  • Note that non-server clients seem to execute the on-remove actions as expected. This only affects the authority game instance.
Callstack

UnrealEditor-GameplayAbilities.dll!FActiveGameplayCueContainer::RemoveCue(const FGameplayTag & Tag) Line 376    C++
UnrealEditor-GameplayAbilities.dll!UAbilitySystemComponent::RemoveGameplayCue_Internal(const FGameplayTag GameplayCueTag, FActiveGameplayCueContainer & GameplayCueContainer) Line 1419    C++
UnrealEditor-GameplayAbilities.dll!UAbilitySystemComponent::RemoveGameplayCue_MinimalReplication(const FGameplayTag GameplayCueTag) Line 1407    C++
UnrealEditor-GameplayAbilities.dll!FActiveGameplayEffectsContainer::RemoveActiveGameplayEffectGrantedTagsAndModifiers(const FActiveGameplayEffect & Effect, bool bInvokeGameplayCueEvents) Line 4670    C++
UnrealEditor-GameplayAbilities.dll!FActiveGameplayEffectsContainer::InternalOnActiveGameplayEffectRemoved(FActiveGameplayEffect & Effect, bool bInvokeGameplayCueEvents, const FGameplayEffectRemovalInfo & GameplayEffectRemovalInfo) Line 4588    C++
UnrealEditor-GameplayAbilities.dll!FActiveGameplayEffectsContainer::InternalRemoveActiveGameplayEffect(int Idx, int StacksToRemove, bool bPrematureRemoval) Line 4519    C++
UnrealEditor-GameplayAbilities.dll!FActiveGameplayEffectsContainer::CheckDuration(FActiveGameplayEffectHandle Handle) Line 5097    C++
[Inline Frame] UnrealEditor-GameplayAbilities.dll!Invoke(void(UAbilitySystemComponent::*)(FActiveGameplayEffectHandle)) Line 66    C++

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-221997 in the post.

0
Login to Vote

Unresolved
CreatedAug 16, 2024
UpdatedAug 19, 2024
View Jira Issue