第一次提交

This commit is contained in:
不明不惑
2026-03-03 01:23:02 +08:00
commit 3e434877e8
1053 changed files with 102411 additions and 0 deletions

View File

@@ -0,0 +1,46 @@
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Abilities/Tasks/AbilityTask_NetworkSyncPoint.h"
#include "GGA_AbilityTask_NetworkSyncPoint.generated.h"
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FGGA_SyncTimeOutDelegate);
/**
*
*/
UCLASS()
class GENERICGAMEPLAYABILITIES_API UGGA_AbilityTask_NetworkSyncPoint : public UAbilityTask_NetworkSyncPoint
{
GENERATED_BODY()
/**
*
* Synchronize execution flow between Client and Server. Depending on SyncType, the Client and Server will wait for the other to reach this node or another WaitNetSync node in the ability before continuing execution.
*
* BothWait - Both Client and Server will wait until the other reaches the node. (Whoever gets their first, waits for the other before continueing).
* OnlyServerWait - Only server will wait for the client signal. Client will signal and immediately continue without waiting to hear from Server.
* OnlyClientWait - Only client will wait for the server signal. Server will signal and immediately continue without waiting to hear from Client.
*
* Note that this is "ability instance wide". These sync points never affect sync points in other abilities.
*
* In most cases you will have both client and server execution paths connected to the same WaitNetSync node. However it is possible to use separate nodes
* for cleanliness of the graph. The "signal" is "ability instance wide".
*
*/
UFUNCTION(BlueprintCallable, Category="Ability|Tasks", meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE"))
static UGGA_AbilityTask_NetworkSyncPoint* WaitNetSyncWithTimeout(UGameplayAbility* OwningAbility, EAbilityTaskNetSyncType SyncType, float WaitTime = 0.2f);
virtual void Activate() override;
protected:
void OnTimeFinish();
float Time;
float TimeStarted;
};

View File

@@ -0,0 +1,223 @@
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Animation/AnimInstance.h"
#include "Abilities/Tasks/AbilityTask.h"
#include "GGA_AbilityTask_PlayMontageAndWaitForEvent.generated.h"
USTRUCT(BlueprintType)
struct FGGA_PlayMontageAndWaitForEventTaskParams
{
GENERATED_BODY()
/**
* Set to override the name of this task, for later querying
* 为此任务设置重载名,以便以后查询
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GGA")
FName TaskInstanceName;
/**
* The montage to play on the character
* 角色要播放的蒙太奇。
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GGA")
TObjectPtr<UAnimMontage> MontageToPlay = nullptr;
/**
* Any gameplay events matching this tag will activate the EventReceived callback. If empty, all events will trigger callback
* 任何与此标签匹配的游戏事件都将激活 EventReceived 回调。如果为空,所有事件都将触发回调
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GGA")
FGameplayTagContainer EventTags;
/**
* Change to play the montage faster or slower
* 更改蒙太奇的播放速度快慢
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GGA")
float Rate = 1.f;
/**
* If not empty, named montage section to start from
* 如果不为空,则从命名的蒙太奇部分开始播放
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GGA")
FName StartSection = NAME_None;
/**
* If true, this montage will be aborted if the ability ends normally. It is always stopped when the ability is explicitly cancelled
* 如果为 "true"那么Ability正常结束时蒙太奇会中止。当该Ability被明确取消时蒙太奇总是会停止。
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GGA")
bool bStopWhenAbilityEnds = true;
/**
* Change to modify size of root motion or set to 0 to block it entirely
* 更改以修改根运动的大小,或设置为 0 以完全阻止它
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GGA")
float AnimRootMotionTranslationScale = 1.f;
/**
* Starting time offset in montage, this will be overridden by StartSection if that is also set
* 蒙太奇中的起始时间偏移,如果也设置了 StartSection则会被 StartSection 覆盖
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GGA")
float StartTimeSeconds = 0.f;
/**
* If true, you can receive OnInterrupted after an OnBlendOut started (otherwise OnInterrupted will not fire when interrupted, but you will not get OnComplete).
* 如果为 "true",则可以在 OnBlendOut 开始后接收 OnInterrupted否则被中断时不会触发 OnInterrupted但也不会收到 OnComplete
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="GGA")
bool bAllowInterruptAfterBlendOut = false;
};
/**
* This task combines PlayMontageAndWait and WaitForEvent into one task, so you can wait for multiple types of activations such as from a melee combo
* Much of this code is copied from one of those two ability tasks
* This is a good task to look at as an example when creating game-specific tasks
* It is expected that each game will have a set of game-specific tasks to do what they want
* 此任务将 PlayMontageAndWait 和 WaitForEvent 合并为一个任务,因此您可以等待多种类型的激活,例如来自近战连击的激活。
* 本任务的大部分代码都是从这两个能力任务中的一个复制过来的
* 在创建特定游戏任务时,这是一个很好的任务示例
* 预计每个游戏都会有一套特定于游戏的任务来完成他们想要做的事情
*/
UCLASS()
class GENERICGAMEPLAYABILITIES_API UGGA_AbilityTask_PlayMontageAndWaitForEvent : public UAbilityTask
{
GENERATED_BODY()
public:
// Constructor and overrides
UGGA_AbilityTask_PlayMontageAndWaitForEvent(const FObjectInitializer& ObjectInitializer);
/** Delegate type used, EventTag and Payload may be empty if it came from the montage callbacks */
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FPlayMontageAndWaitForEventDelegate, FGameplayTag, EventTag, FGameplayEventData, EventData);
/** The montage completely finished playing */
UPROPERTY(BlueprintAssignable)
FPlayMontageAndWaitForEventDelegate OnCompleted;
UPROPERTY(BlueprintAssignable)
FPlayMontageAndWaitForEventDelegate OnBlendedIn;
/** The montage started blending out */
UPROPERTY(BlueprintAssignable)
FPlayMontageAndWaitForEventDelegate OnBlendOut;
/** The montage was interrupted */
UPROPERTY(BlueprintAssignable)
FPlayMontageAndWaitForEventDelegate OnInterrupted;
/** The ability task was explicitly cancelled by another ability */
UPROPERTY(BlueprintAssignable)
FPlayMontageAndWaitForEventDelegate OnCancelled;
/** One of the triggering gameplay events happened */
UPROPERTY(BlueprintAssignable)
FPlayMontageAndWaitForEventDelegate EventReceived;
UFUNCTION()
void OnMontageBlendedIn(UAnimMontage* Montage);
UFUNCTION()
void OnMontageBlendingOut(UAnimMontage* Montage, bool bInterrupted);
/** Callback function for when the owning Gameplay Ability is cancelled */
UFUNCTION()
void OnGameplayAbilityCancelled();
void OnMontageEnded(UAnimMontage* Montage, bool bInterrupted);
void OnGameplayEvent(FGameplayTag EventTag, const FGameplayEventData* Payload);
/**
* See PlayMontageAndWaitForEventExt for details。
* 查看 PlayMontageAndWaitForEventExt 以获得更多注释。
*/
UFUNCTION(BlueprintCallable, Category = "GGA|Tasks", meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE"))
static UGGA_AbilityTask_PlayMontageAndWaitForEvent* PlayMontageAndWaitForEvent(
UGameplayAbility* OwningAbility,
FName TaskInstanceName,
UAnimMontage* MontageToPlay,
FGameplayTagContainer EventTags,
float Rate = 1.f,
FName StartSection = NAME_None,
bool bStopWhenAbilityEnds = true,
float AnimRootMotionTranslationScale = 1.f,
float StartTimeSeconds = 0.f,
bool bAllowInterruptAfterBlendOut = false);
/**
* Play a montage and wait for it end. If a gameplay event happens that matches EventTags (or EventTags is empty), the EventReceived delegate will fire with a tag and event data.
* If StopWhenAbilityEnds is true, this montage will be aborted if the ability ends normally. It is always stopped when the ability is explicitly cancelled.
* On normal execution, OnBlendOut is called when the montage is blending out, and OnCompleted when it is completely done playing
* OnInterrupted is called if another montage overwrites this, and OnCancelled is called if the ability or task is cancelled
* 播放蒙太奇并等待结束。如果发生了符合 EventTags 的游戏事件(或 EventTags 为空EventReceived 委托就会触发,并带有标签和事件数据。
* 如果 StopWhenAbilityEnds 为 true那么如果能力正常结束蒙太奇将会中止。当能力被明确取消时蒙太奇始终会停止。
* 在正常执行时,蒙太奇混合结束时会调用 OnBlendOut完全结束时会调用 OnCompleted。
* 如果其他蒙太奇覆盖了该功能,则调用 OnInterrupted如果取消了该功能或任务则调用 OnCancelled。
*/
UFUNCTION(BlueprintCallable, Category = "GGA|Tasks", meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE"))
static UGGA_AbilityTask_PlayMontageAndWaitForEvent* PlayMontageAndWaitForEventExt(UGameplayAbility* OwningAbility, FGGA_PlayMontageAndWaitForEventTaskParams Params);
/**
* The Blueprint node for this task, PlayMontageAndWaitForEvent, has some black magic from the plugin that automagically calls Activate()
* inside of K2Node_LatentAbilityCall as stated in the AbilityTask.h. Ability logic written in C++ probably needs to call Activate() itself manually.
*/
virtual void Activate() override;
/** Called when the ability is asked to cancel from an outside node. What this means depends on the individual task. By default, this does nothing other than ending the task. */
virtual void ExternalCancel() override;
virtual FString GetDebugString() const override;
UFUNCTION(BlueprintCallable, Category="GGA|Tasks")
void EndTaskByOwner();
protected:
virtual void OnDestroy(bool AbilityEnded) override;
/** Checks if the ability is playing a montage and stops that montage, returns true if a montage was stopped, false if not. */
bool StopPlayingMontage();
FOnMontageBlendedInEnded BlendedInDelegate;
FOnMontageBlendingOutStarted BlendingOutDelegate;
FOnMontageEnded MontageEndedDelegate;
FDelegateHandle InterruptedHandle;
FDelegateHandle EventHandle;
/** Montage that is playing */
UPROPERTY()
TObjectPtr<UAnimMontage> MontageToPlay;
/** List of tags to match against gameplay events */
UPROPERTY()
FGameplayTagContainer EventTags;
/** Playback rate */
UPROPERTY()
float Rate;
/** Section to start montage from */
UPROPERTY()
FName StartSection;
/** Modifies how root motion movement to apply */
UPROPERTY()
float AnimRootMotionTranslationScale;
UPROPERTY()
float StartTimeSeconds;
/** Rather montage should be aborted if ability ends */
UPROPERTY()
bool bStopWhenAbilityEnds;
UPROPERTY()
bool bAllowInterruptAfterBlendOut;
};

View File

@@ -0,0 +1,48 @@
//// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
//
//#pragma once
//
//#include "CoreMinimal.h"
//#include "Abilities/Tasks/AbilityTask.h"
//#include "Runtime/Launch/Resources/Version.h"
//#if ENGINE_MINOR_VERSION < 5
//#include "InstancedStruct.h"
//#else
//#include "StructUtils/InstancedStruct.h"
//#endif
//#include "GGA_AbilityTask_RunCustomAbilityTask.generated.h"
//
//
//class UGGA_CustomAbilityTask;
//DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FGGA_CustomAbilityTaskDelegate, const FGameplayTag, EventTag, const FInstancedStruct&, Payload);
//
///**
// * A special ability task runs GGA_CustomAbilityTask internally.
// */
//UCLASS()
//class GENERICGAMEPLAYABILITIES_API UGGA_AbilityTask_RunCustomAbilityTask : public UAbilityTask
//{
// GENERATED_BODY()
//
//public:
// UGGA_AbilityTask_RunCustomAbilityTask();
//
// UPROPERTY(BlueprintAssignable)
// FGGA_CustomAbilityTaskDelegate OnEvent;
//
// virtual void GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const override;
//
// // Like WaitDelay but only delays one frame (tick).
// UFUNCTION(BlueprintCallable, Category = "GGA|Tasks", meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE"))
// static UGGA_AbilityTask_RunCustomAbilityTask* RunCustomAbilityTask(UGameplayAbility* OwningAbility, TSoftClassPtr<UGGA_CustomAbilityTask> AbilityTaskClass);
//
// virtual void Activate() override;
// virtual void TickTask(float DeltaTime) override;
// virtual void OnDestroy(bool bInOwnerFinished) override;
//
// virtual void InitSimulatedTask(UGameplayTasksComponent& InGameplayTasksComponent) override;
//
//private:
// UPROPERTY(Replicated)
// TObjectPtr<UGGA_CustomAbilityTask> TaskInstance{nullptr};
//};

View File

@@ -0,0 +1,37 @@
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Abilities/Tasks/AbilityTask.h"
#include "Abilities/Tasks/AbilityTask_WaitTargetData.h"
#include "GGA_AbilityTask_ServerWaitForClientTargetData.generated.h"
UCLASS()
class GENERICGAMEPLAYABILITIES_API UGGA_AbilityTask_ServerWaitForClientTargetData : public UAbilityTask
{
GENERATED_UCLASS_BODY()
UPROPERTY(BlueprintAssignable)
FWaitTargetDataDelegate ValidData;
/**
* The server side waits for target data from the client.
* Client execution of this node will return directly from ActivatePin and continue execution
* 服务端等待客户端的目标数据。
* 客户端执行这个节点会直接从ActivatePin返回并继续执行
*/
UFUNCTION(BlueprintCallable, meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "true", HideSpawnParms = "Instigator"), Category = "GGA|Tasks")
static UGGA_AbilityTask_ServerWaitForClientTargetData* ServerWaitForClientTargetData(UGameplayAbility* OwningAbility, FName TaskInstanceName, bool TriggerOnce);
virtual void Activate() override;
UFUNCTION()
void OnTargetDataReplicatedCallback(const FGameplayAbilityTargetDataHandle& Data, FGameplayTag ActivationTag);
protected:
virtual void OnDestroy(bool AbilityEnded) override;
bool bTriggerOnce;
};

View File

@@ -0,0 +1,30 @@
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Abilities/Tasks/AbilityTask.h"
#include "GGA_AbilityTask_WaitDelayOneFrame.generated.h"
/**
* Like WaitDelay but only delays one frame (tick).
*/
UCLASS()
class GENERICGAMEPLAYABILITIES_API UGGA_AbilityTask_WaitDelayOneFrame : public UAbilityTask
{
GENERATED_UCLASS_BODY()
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FWaitDelayOneFrameDelegate);
UPROPERTY(BlueprintAssignable)
FWaitDelayOneFrameDelegate OnFinish;
virtual void Activate() override;
// Like WaitDelay but only delays one frame (tick).
UFUNCTION(BlueprintCallable, Category = "GGA|Tasks", meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE"))
static UGGA_AbilityTask_WaitDelayOneFrame* WaitDelayOneFrame(UGameplayAbility* OwningAbility);
private:
void OnDelayFinish();
};

View File

@@ -0,0 +1,52 @@
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "GameplayTagContainer.h"
#include "Abilities/GameplayAbilityTypes.h"
#include "Abilities/Tasks/AbilityTask.h"
#include "GGA_AbilityTask_WaitGameplayEvents.generated.h"
class UAbilitySystemComponent;
UCLASS()
class GENERICGAMEPLAYABILITIES_API UGGA_AbilityTask_WaitGameplayEvents : public UAbilityTask
{
GENERATED_UCLASS_BODY()
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FWaitGameplayEventsDelegate, FGameplayTag, EventTag, FGameplayEventData, EventData);
UPROPERTY(BlueprintAssignable)
FWaitGameplayEventsDelegate EventReceived;
/**
* Wait until the specified gameplay tags event is triggered. By default this will look at the owner of this ability. OptionalExternalTarget can be set to make this look at another actor's tags for changes
* It will keep listening as long as OnlyTriggerOnce = false
*/
UFUNCTION(BlueprintCallable, Category = "GGA|Tasks", meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE"))
static UGGA_AbilityTask_WaitGameplayEvents* WaitGameplayEvents(UGameplayAbility* OwningAbility, FGameplayTagContainer EventTags, AActor* OptionalExternalTarget = nullptr,
bool OnlyTriggerOnce = false);
void SetExternalTarget(AActor* Actor);
UAbilitySystemComponent* GetTargetASC();
virtual void Activate() override;
virtual void GameplayEventContainerCallback(FGameplayTag MatchingTag, const FGameplayEventData* Payload);
void OnDestroy(bool AbilityEnding) override;
/** List of tags to match against gameplay events */
UPROPERTY()
FGameplayTagContainer EventTags;
UPROPERTY()
TObjectPtr<UAbilitySystemComponent> OptionalExternalTarget;
bool UseExternalTarget;
bool OnlyTriggerOnce;
FDelegateHandle MyHandle;
};

View File

@@ -0,0 +1,68 @@
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Abilities/Tasks/AbilityTask.h"
#include "GGA_AbilityTask_WaitInputPressWithTags.generated.h"
/**
* Waits until the input is pressed from activating an ability and the ASC has the required tags and not the ignored tags.
* This should be true immediately upon starting the ability, since the key was pressed to activate it. We expect server to
* execute this task in parallel and keep its own time.
*/
UCLASS()
class GENERICGAMEPLAYABILITIES_API UGGA_AbilityTask_WaitInputPressWithTags : public UAbilityTask
{
GENERATED_UCLASS_BODY()
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FInputPressWithTagsDelegate, float, TimeWaited);
UPROPERTY(BlueprintAssignable)
FInputPressWithTagsDelegate OnPress;
virtual void Activate() override;
UFUNCTION()
void OnPressCallback();
/**
* Wait until the user presses the input button for this ability's activation. Returns time this node spent waiting for the press. Will return 0 if input was already down.
* This is hardcoded for GA_InteractPassive to not fire when State.Interacting TagCount is > State.InteractingRemoval TagCount.
* //TODO Ideally the RequiredTags, IgnoredTags, and State.Interacting TagCount would get moved into a subclass of FGameplayTagQuery and then we'd only expose that as one
* parameter and rename the task to WaitInputPress_Query.
*
* @param RequiredTags Ability Owner must have all of these tags otherwise the input is ignored.
* @param IgnoredTags Ability Owner cannot have any of these tags otherwise the input is ignored.
*/
UFUNCTION(BlueprintCallable, Category = "GGA|Tasks",
meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE", DeprecatedFunction, DeprecationMessage="Use WaitInputPressWithTagQuery"))
static UGGA_AbilityTask_WaitInputPressWithTags* WaitInputPressWithTags(UGameplayAbility* OwningAbility, FGameplayTagContainer RequiredTags, FGameplayTagContainer IgnoredTags,
bool bTestAlreadyPressed = false);
/**
* Wait until the user presses the input button for this ability's activation. Returns time this node spent waiting for the press. Will return 0 if input was already down.
* @param OwningAbility The ability owning this task.
* @param TagQuery Ability Owner must match this tag query otherwise the input is ignored.
* @param bTestAlreadyPressed Test if already pressed.
*/
UFUNCTION(BlueprintCallable, Category = "GGA|Tasks",
meta = (HidePin = "OwningAbility", DefaultToSelf = "OwningAbility", BlueprintInternalUseOnly = "TRUE", DeprecatedFunction, DeprecationMessage="Use WaitInputPressWithQuery"))
static UGGA_AbilityTask_WaitInputPressWithTags* WaitInputPressWithTagQuery(UGameplayAbility* OwningAbility, const FGameplayTagQuery& TagQuery, bool bTestAlreadyPressed = false);
protected:
float StartTime;
bool bTestInitialState;
FDelegateHandle DelegateHandle;
FGameplayTagQuery TagQuery;
virtual void OnDestroy(bool AbilityEnded) override;
/**
* We can only listen for one input pressed event. I think it's because
* UAbilitySystemComponent::InvokeReplicatedEvent sets ReplicatedData->GenericEvents[(uint8)EventType].bTriggered = true;
* So if we want to keep listening for more input events, we just clear the delegate handle and bind again.
*/
virtual void Reset();
};

View File

@@ -0,0 +1,86 @@
// Copyright 2025 https://yuewu.dev/en All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Abilities/GameplayAbilityTargetActor.h"
#include "Abilities/Tasks/AbilityTask.h"
#include "GGA_AbilityTask_WaitTargetDataUsingActor.generated.h"
/**
* 从一个已经生成的TargetActor中等待TargetData当接收到有效数据后并不销毁这个TargetActor。
* 是原版本的WaitTargetData的重写并添加了bCreateKeyIfNotValidForMorePredicting的功能。
*/
UCLASS()
class GENERICGAMEPLAYABILITIES_API UGGA_AbilityTask_WaitTargetDataUsingActor : public UAbilityTask
{
GENERATED_BODY()
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FWaitTargetDataUsingActorDelegate, const FGameplayAbilityTargetDataHandle&,Data);
UPROPERTY(BlueprintAssignable)
FWaitTargetDataUsingActorDelegate ValidData;
UPROPERTY(BlueprintAssignable)
FWaitTargetDataUsingActorDelegate Cancelled;
/** 传入一个已经生成的TargetActor并等待返回有效数据或者取消,这个TargetActor在使用后不会被销毁。
*
* @param bCreateKeyIfNotValidForMorePredicting Will create a new scoped prediction key if the current scoped prediction key is not valid for more predicting.
* If false, it will always create a new scoped prediction key. We would want to set this to true if we want to use a potentially existing valid scoped prediction
* key like the ability's activation key in a batched ability.
*/
UFUNCTION(BlueprintCallable, Category = "GGA|Tasks", meta=(HidePin = "OwningAbility", DefaultToSelf =
"OwningAbility",
BlueprintInternalUseOnly=
"true", HideSpawnParms="Instigator"))
static UGGA_AbilityTask_WaitTargetDataUsingActor* WaitTargetDataWithReusableActor(
UGameplayAbility* OwningAbility, FName TaskInstanceName,
TEnumAsByte<EGameplayTargetingConfirmation::Type> ConfirmationType,
AGameplayAbilityTargetActor* InTargetActor, bool bCreateKeyIfNotValidForMorePrediction = false);
virtual void Activate() override;
/** server处理TargetDataSet事件 */
UFUNCTION()
virtual void OnTargetDataReplicatedCallback(const FGameplayAbilityTargetDataHandle& Data,
FGameplayTag ActivationTag);
/** server处理TargetDataCancelled事件 */
UFUNCTION()
virtual void OnTargetDataReplicatedCancelledCallback();
/** 玩家Confirm目标后触发(TargetActor->ConfirmTargeting) */
UFUNCTION()
virtual void OnTargetDataReadyCallback(const FGameplayAbilityTargetDataHandle& Data);
/** 玩家Cancel目标后触发(TargetActor->CancelTargeting) */
UFUNCTION()
virtual void OnTargetDataCancelledCallback(const FGameplayAbilityTargetDataHandle& Data);
// Called when the ability is asked to confirm from an outside node. What this means depends on the individual task. By default, this does nothing other than ending if bEndTask is true.
virtual void ExternalConfirm(bool bEndTask) override;
// Called when the ability is asked to cancel from an outside node. What this means depends on the individual task. By default, this does nothing other than ending the task.
virtual void ExternalCancel() override;
protected:
UPROPERTY()
TObjectPtr<AGameplayAbilityTargetActor> TargetActor;
bool bCreateKeyIfNotValidForMorePrediction;
TEnumAsByte<EGameplayTargetingConfirmation::Type> ConfirmationType;
virtual void InitializeTargetActor() const;
virtual void RegisterTargetDataCallbacks();
virtual void FinalizeTargetActor() const;
void OnDestroy(bool AbilityEnded) override;
/**
* 如果是客户端且传入的TargetActor不能在服务端产生TargetData则返回真
*/
virtual bool ShouldReplicateDataToServer() const;
};