void UGameplayCueNotify_Static::HandleGameplayCue(AActor* MyTarget, EGameplayCueEvent::Type EventType, FGameplayCueParameters Parameters) { if (MyTarget && !MyTarget->IsPendingKill()) { K2_HandleGameplayCue(MyTarget, EventType, Parameters); switch (EventType) { case EGameplayCueEvent::OnActive: OnActive(MyTarget, Parameters); break; case EGameplayCueEvent::WhileActive: WhileActive(MyTarget, Parameters); break; case EGameplayCueEvent::Executed: OnExecute(MyTarget, Parameters); break; case EGameplayCueEvent::Removed: OnRemove(MyTarget, Parameters); break; }; } else { ABILITY_LOG(Warning, TEXT("Null Target")); } }
void AGameplayCueNotify_Actor::HandleGameplayCue(AActor* MyTarget, EGameplayCueEvent::Type EventType, const FGameplayCueParameters& Parameters) { SCOPE_CYCLE_COUNTER(STAT_HandleGameplayCueNotifyActor); if (Parameters.MatchedTagName.IsValid() == false) { ABILITY_LOG(Warning, TEXT("GameplayCue parameter is none for %s"), *GetNameSafe(this)); } // Handle multiple event gating { if (EventType == EGameplayCueEvent::OnActive && !bAllowMultipleOnActiveEvents && bHasHandledOnActiveEvent) { return; } if (EventType == EGameplayCueEvent::WhileActive && !bAllowMultipleWhileActiveEvents && bHasHandledWhileActiveEvent) { return; } if (EventType == EGameplayCueEvent::Removed && bHasHandledOnRemoveEvent) { return; } } // If cvar is enabled, check that the target no longer has the matched tag before doing remove logic. This is a simple way of supporting stacking, such that if an actor has two sources giving him the same GC tag, it will not be removed when the first one is removed. if (GameplayCueNotifyTagCheckOnRemove > 0 && EventType == EGameplayCueEvent::Removed) { if (IGameplayTagAssetInterface* TagInterface = Cast<IGameplayTagAssetInterface>(MyTarget)) { if (TagInterface->HasMatchingGameplayTag(Parameters.MatchedTagName)) { return; } } } if (MyTarget && !MyTarget->IsPendingKill()) { K2_HandleGameplayCue(MyTarget, EventType, Parameters); // Clear any pending auto-destroy that may have occurred from a previous OnRemove SetLifeSpan(0.f); switch (EventType) { case EGameplayCueEvent::OnActive: OnActive(MyTarget, Parameters); bHasHandledOnActiveEvent = true; break; case EGameplayCueEvent::WhileActive: WhileActive(MyTarget, Parameters); bHasHandledWhileActiveEvent = true; break; case EGameplayCueEvent::Executed: OnExecute(MyTarget, Parameters); break; case EGameplayCueEvent::Removed: bHasHandledOnRemoveEvent = true; OnRemove(MyTarget, Parameters); if (bAutoDestroyOnRemove) { if (AutoDestroyDelay > 0.f) { FTimerDelegate Delegate = FTimerDelegate::CreateUObject(this, &AGameplayCueNotify_Actor::GameplayCueFinishedCallback); GetWorld()->GetTimerManager().SetTimer(FinishTimerHandle, Delegate, AutoDestroyDelay, false); } else { GameplayCueFinishedCallback(); } } break; }; } else { ABILITY_LOG(Warning, TEXT("Null Target called for event %d on GameplayCueNotifyActor %s"), (int32)EventType, *GetName() ); if (EventType == EGameplayCueEvent::Removed) { // Make sure the removed event is handled so that we don't leak GC notify actors GameplayCueFinishedCallback(); } } }