结构
Module | GameplayAbilities |
Header | /Engine/Plugins/Runtime/GameplayAbilities/Source/GameplayAbilities/Public/Abilities/Tasks/AbilityTask_Repeat.h |
Include | #include “Abilities/Tasks/AbilityTask_Repeat.h” |
Syntax | UCLASS () class UAbilityTask_Repeat : public UAbilityTask |
Remarks | Repeat a task a certain number of times at a given interval. |
用途
从名字和描述可以看出来,这个类是用来将一个 task 重复执行多次的。
具体说,比如要重复执行一个任务,次数为 3,时间间隔为 0.2s,就像潘森的e技能:
每个一段时间计算一次伤害,这种技能在各种游戏中都很常见。
用法
主要使用的是 RepeatAction
函数和 OnPerformAction
委托函数。
RepeatAction
函数用来创建一个重复的任务,比如叫 RepeatTask:
UAbilityTask_Repeat* RepeatTask = UAbilityTask_Repeat::RepeatAction(this, Interval, Times);
其中 Interval 是每次的时间间隔,Times 是重复次数,可以自己设,如果想在蓝图中给策划进行配置,就在数据前加上 UPROPERTY(EditAnywhere)
。
在 UAbilityTask_Repeat::Activate()
函数中可以看到,实际重复以及控制时间间隔使用了 World->GetTimerManager().SetTimer
方法(这里不展开),实际重复的任务的调用是里边的 PerformAction();
函数,这个函数里会用 OnPerformAction.Broadcast(ActionCounter); 来进行广播。
OnPerformAction
是一个代理函数。
UPROPERTY(BlueprintAssignable)
FRepeatedActionDelegate OnPerformAction;
代理的设置是(关于 UE4 的代理可以参考 待填写):
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FRepeatedActionDelegate, int32, ActionNumber);
也就是一个 接收一个参数 的 动态多播。需要使用 AddDynamic
进行动态绑定。但是这个代理接受的参数是一个 int32 类型的整数,但是我们又需要传递别的参数的话,就需要设计一个代理类,来进行中间商的操作:
UCLASS()
class URepeatActionProxy : public UObject
{
GENERATED_BODY()
public:
FGameplayTag MyTag;
DataType MyData;
TWeakObjectPtr<UGameplayAbility> Ability;
UFUNCTION()
void OnPerform(int32 Counter)
{
ensure(Ability.IsValid());
Ability->DoSomeThing(MyTag, MyData);
}
};
使用这样的代理类,接收了参数之后,使用一个中间函数,调用本身需要重复调用的函数 (DoSomeThing
),其中 MyTag
和 MyData
是需要传递的参数。
这样就可以通过:
UAbilityTask_Repeat* RepeatTask = UAbilityTask_Repeat::RepeatAction(this, Interval, Times);
URepeatActionProxy* Proxy = NewObject<URepeatActionProxy>(this);
Proxy->Ability = this;
Proxy->MyData = MyData;
RepeatTask->OnPerformAction.AddDynamic(Proxy, &URepeatActionProxy::OnPerform);
RepeatTask->ReadyForActivation();
进行技能的重复执行了(动画还是一个动画)。
值得注意的是,在 UGameplayAbility
中,this
指针,就是 Ability
。