UnrealEngine GameplayAbilitySystem Effect Cooldown剩余时间监听

 并未考虑网络复制等等网络问题

// Copyright 2022 - 2024 Dream Moon Team. All Rights Reserved.

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "GameplayTags.h"
#include "AbilitySystemComponent.h"
#include "AsyncTaskCooldownChange.generated.h"

/**
 *
 */
UCLASS(BlueprintType, meta=(ExposedAsyncProxy = AsyncTask))
class DREAMGAMEPLAY_API UAsyncTaskCooldownChange : public UBlueprintAsyncActionBase
{
	GENERATED_BODY()

public:
	DECLARE_DYNAMIC_MULTICAST_DELEGATE_FourParams(FOnCooldownBegin, const FGameplayTagContainer&, CooldownTag, TSubclassOf<UGameplayEffect>, EffectClass, float, TimeRemaining, float, Duration);
	DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnCooldownEnd, const FGameplayTagContainer&, CooldownTag, TSubclassOf<UGameplayEffect>, EffectClass);
public:
	UPROPERTY(BlueprintAssignable)
	FOnCooldownBegin OnCooldownBegin;

	UPROPERTY(BlueprintAssignable)
	FOnCooldownEnd OnCooldownEnd;

	UFUNCTION(BlueprintCallable, meta=(BlueprintInternalUseOnly = "true"))
	static UAsyncTaskCooldownChange* ListenForCooldownChange(UAbilitySystemComponent* AbilitySystemComponent, FGameplayTagContainer CooldownTag, bool bUseServerCooldown);

protected:
	UPROPERTY()
	UAbilitySystemComponent* AbilitySystemComp;
	FGameplayTagContainer CooldownsToListenFor;
	void OnCooldownBeginDelegate(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec, FActiveGameplayEffectHandle Handle);
	void OnCooldownEndDelegate(const FActiveGameplayEffect& Effect);
};
// Copyright 2022 - 2024 Dream Moon Team. All Rights Reserved.


#include "Ability/AsyncTaskCooldownChange.h"

UAsyncTaskCooldownChange* UAsyncTaskCooldownChange::ListenForCooldownChange(
	UAbilitySystemComponent* AbilitySystemComponent, FGameplayTagContainer CooldownTag, bool bUseServerCooldown)
{
	UAsyncTaskCooldownChange* Node = NewObject<UAsyncTaskCooldownChange>();
	Node->AbilitySystemComp = AbilitySystemComponent;
	Node->CooldownsToListenFor = CooldownTag;
	if (!IsValid(AbilitySystemComponent) || !CooldownTag.IsValid())
	{
		Node->RemoveFromRoot();
		return nullptr;
	}

	AbilitySystemComponent->OnActiveGameplayEffectAddedDelegateToSelf.AddUObject(Node, &UAsyncTaskCooldownChange::OnCooldownBeginDelegate);
	AbilitySystemComponent->OnAnyGameplayEffectRemovedDelegate().AddUObject(Node, &UAsyncTaskCooldownChange::OnCooldownEndDelegate);
	return Node;
}

void UAsyncTaskCooldownChange::OnCooldownBeginDelegate(UAbilitySystemComponent* ASC, const FGameplayEffectSpec& Spec,
	FActiveGameplayEffectHandle Handle)
{
	FGameplayEffectQuery Query = FGameplayEffectQuery::MakeQuery_MatchAnyOwningTags(CooldownsToListenFor);
	TArray< TPair<float, float> > DurationAndTimeRemaining = ASC->GetActiveEffectsTimeRemainingAndDuration(Query);
	if (DurationAndTimeRemaining.Num() > 0)
	{
		int32 BestIdx = 0;
		float LongestTime = DurationAndTimeRemaining[0].Key;
		for (int32 Idx = 1; Idx < DurationAndTimeRemaining.Num(); ++Idx)
		{
			if (DurationAndTimeRemaining[Idx].Key > LongestTime)
			{
				LongestTime = DurationAndTimeRemaining[Idx].Key;
				BestIdx = Idx;
			}
		}
		/*	Result	*/
		OnCooldownBegin.Broadcast(CooldownsToListenFor,
			Spec.Def.GetClass(),
			DurationAndTimeRemaining[BestIdx].Key,
			DurationAndTimeRemaining[BestIdx].Value);
	}
}

void UAsyncTaskCooldownChange::OnCooldownEndDelegate(const FActiveGameplayEffect& Effect)
{
	FGameplayEffectQuery Query = FGameplayEffectQuery::MakeQuery_MatchAnyOwningTags(CooldownsToListenFor);
	OnCooldownEnd.Broadcast(CooldownsToListenFor, Effect.Spec.Def.GetClass());
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值