这一篇文章主要是对GA的源码定义文件的解析,方便后续学习对GA内部的内容做一个了解,而不是去学习GA的实现。
首先对源码注释进行一个了解
// Copyright Epic Games, Inc. All Rights Reserved.#pragma once#include "CoreMinimal.h"// 包含核心模块的最小定义
#include "UObject/ObjectMacros.h"// 包含UObject的宏定义
#include "UObject/Object.h"// 包含UObject类的定义
#include "Templates/SubclassOf.h"// 包含子类模板的定义
#include "GameplayTagContainer.h"// 包含游戏标签容器的定义
#include "GameplayEffectTypes.h" // 包含游戏效果类型的声明
#include "GameplayAbilitySpec.h"// 包含游戏技能实例的定义
#include "GameplayEffect.h"// 包含游戏效果的定义
#include "Abilities/GameplayAbilityTypes.h"// 包含游戏技能类型的声明
#include "GameplayTaskOwnerInterface.h" // 包含游戏技能任务所有者接口的定义
#include "Abilities/GameplayAbilityTargetTypes.h"// 包含游戏技能目标类型的声明
#include "GameplayAbility.generated.h" // 包含游戏技能生成的头文件// 声明一些与游戏技能相关的类
class UAbilitySystemComponent;
class UAnimMontage;
class UGameplayAbility;
class UGameplayTask;
class UGameplayTasksComponent;// 定义一个结构体,用于在激活技能时启用日志记录
struct FScopedCanActivateAbilityLogEnabler
{FScopedCanActivateAbilityLogEnabler() { ++LogEnablerCounter; }// 构造函数,增加日志记录计数器~FScopedCanActivateAbilityLogEnabler() { --LogEnablerCounter; }// 析构函数,减少日志记录计数器static bool IsLoggingEnabled() { return LogEnablerCounter > 0; }// 静态方法,判断是否启用日志记录private:static int32 LogEnablerCounter; // 日志记录计数器
};/*** UGameplayAbility* * 游戏技能定义了可以被激活或触发的自定义游戏逻辑。* * 技能系统为游戏技能提供的主要功能包括:* -可用性功能:* -冷却时间* -成本(法力、耐力等)* -等等* * -复制支持* -客户端/服务器之间的技能激活通信* -客户端预测技能激活* * -实例化支持* -技能可以是非实例化的(仅本地)* -每个所有者实例化* -每次执行实例化(默认)* * -基础的,可扩展的:* -输入绑定* -'给予' 技能(可以使用)给角色* ** 有关非实例化技能的示例,请参阅GameplayAbility_Montage* -播放蒙太奇并在播放蒙太奇时对其目标应用GameplayEffect。* -完成后,移除GameplayEffect。* * 关于复制支持的注意事项:* -非实例化技能具有有限的复制支持。* -不能有状态(显然),因此没有复制属性* -技能类上的复制不能实现。* * 要支持状态或事件复制,必须实例化技能。这可以通过InstancingPolicy属性完成。*/// 当游戏技能结束时的通知委托定义
DECLARE_MULTICAST_DELEGATE_OneParam(FOnGameplayAbilityEnded, UGameplayAbility*);// 当游戏技能被取消时的通知委托定义
DECLARE_MULTICAST_DELEGATE(FOnGameplayAbilityCancelled);// 用于在状态结束时通知技能状态任务的通知委托
DECLARE_MULTICAST_DELEGATE_OneParam(FOnGameplayAbilityStateEnded, FName);// 用于延迟执行直到我们离开临界区的委托
DECLARE_DELEGATE(FPostLockDelegate);// 定义一个结构体,用于定义技能如何由外部事件触发
USTRUCT()
struct FAbilityTriggerData
{GENERATED_USTRUCT_BODY()// 自动生成USTRUCT所需的代码FAbilityTriggerData() : TriggerSource(EGameplayAbilityTriggerSource::GameplayEvent)// 构造函数,设置触发源为游戏事件{}/** 要响应的标签 */UPROPERTY(EditAnywhere, Category=TriggerData, meta=(Categories="TriggerTagCategory"))FGameplayTag TriggerTag;/** 要响应的触发类型 */UPROPERTY(EditAnywhere, Category=TriggerData)TEnumAsByte<EGameplayAbilityTriggerSource::Type> TriggerSource;
};// 定义一个类,用于定义可以由玩家或外部游戏逻辑激活的自定义游戏逻辑
UCLASS(Blueprintable)
class GAMEPLAYABILITIES_API UGameplayAbility : public UObject, public IGameplayTaskOwnerInterface// 继承自UObject和IGameplayTaskOwnerInterface接口
{GENERATED_UCLASS_BODY()// 友元类声明,这些类可以在反射系统中访问UGameplayAbility的私有成员friend class UAbilitySystemComponent;friend class UGameplayAbilitySet;friend struct FScopedTargetListLock;public:// ----------------------------------------------------------------------------------------------------------------//// The important functions:这段注释解释了UGameplayAbility类中一些重要函数的用途和行为// // CanActivateAbility() - 一个常量函数,用来检查技能是否可以被激活。可以被UI等调用。//// TryActivateAbility() - 尝试激活技能。会调用CanActivateAbility()。输入事件可以直接调用这个函数。// - 也处理每次执行时的实例化逻辑以及复制/预测调用。// // CallActivateAbility() - 受保护的非虚拟函数。做一些激活前的样板工作,然后调用ActivateAbility()。//// ActivateAbility() - 技能所做的操作。子类需要覆盖这个函数。// // CommitAbility() - 提交资源/冷却时间等。ActivateAbility()必须调用这个函数!// // CancelAbility() - 从外部源中断技能。//// EndAbility() - 结束技能。这应该是由技能自身调用以结束自己。// // ----------------------------------------------------------------------------------------------------------------// --------------------------------------// Accessors 访问器// --------------------------------------/** 返回技能在执行时是如何实例化的。这限制了技能在其实现中可以执行的操作。 */EGameplayAbilityInstancingPolicy::Type GetInstancingPolicy() const{return InstancingPolicy;}/** 返回技能如何在网络中复制状态/事件给每个人 */EGameplayAbilityReplicationPolicy::Type GetReplicationPolicy() const{return ReplicationPolicy;}/** 技能在网络中在哪里执行?客户端是“询问并预测”、“询问并等待”还是“不问(直接执行)” */EGameplayAbilityNetExecutionPolicy::Type GetNetExecutionPolicy() const{return NetExecutionPolicy;}/** 技能应该在网络中哪里执行?提供保护,防止客户端尝试执行受限的技能。 */EGameplayAbilityNetSecurityPolicy::Type GetNetSecurityPolicy() const{return NetSecurityPolicy;}/** 返回与此技能关联的演员信息,缓存了指向有用对象的指针 */UFUNCTION(BlueprintCallable, Category=Ability)FGameplayAbilityActorInfo GetActorInfo() const;/** 返回拥有此技能的演员,该演员可能没有物理位置 */UFUNCTION(BlueprintCallable, Category = Ability)AActor* GetOwningActorFromActorInfo() const;/** 返回正在执行此技能的物理演员。可能为null */UFUNCTION(BlueprintCallable, Category = Ability)AActor* GetAvatarActorFromActorInfo() const;/** 对于技能来说,获取骨骼网格组件的便捷方法 - 对于动画技能非常有用 */UFUNCTION(BlueprintCallable, DisplayName = "GetSkeletalMeshComponentFromActorInfo", Category = Ability)USkeletalMeshComponent* GetOwningComponentFromActorInfo() const;/** 返回正在激活此技能的 AbilitySystemComponent */UFUNCTION(BlueprintCallable, Category = Ability)UAbilitySystemComponent* GetAbilitySystemComponentFromActorInfo() const;// 以下是对GetAbilitySystemComponentFromActorInfo的重载,提供了额外的检查和确保机制UAbilitySystemComponent* GetAbilitySystemComponentFromActorInfo_Checked() const;UAbilitySystemComponent* GetAbilitySystemComponentFromActorInfo_Ensured() const;/** 获取当前绑定到此技能的演员信息 - 只能在技能实例中调用 */const FGameplayAbilityActorInfo* GetCurrentActorInfo() const;/** 获取当前绑定到此技能的激活信息 - 只能在技能实例中调用 */FGameplayAbilityActivationInfo GetCurrentActivationInfo() const;/** 获取当前绑定到此技能的激活信息的引用 - 只能在技能实例中调用 */FGameplayAbilityActivationInfo& GetCurrentActivationInfoRef(){// 检查是否为实例化的技能,如果不是,则抛出错误checkf(IsInstantiated(), TEXT("%s: GetCurrentActivationInfoRef cannot be called on a non-instanced ability. Check the instancing policy."), *GetPathName());return CurrentActivationInfo;}/** 获取当前的AbilitySpecHandle - 只能在技能实例中调用 */FGameplayAbilitySpecHandle GetCurrentAbilitySpecHandle() const;/** 检索此技能的实际操作AbilitySpec。只能在技能实例中调用。 */FGameplayAbilitySpec* GetCurrentAbilitySpec() const;/** 检索授予此技能的GameplayEffect的EffectContext。只能在技能实例中调用。 */UFUNCTION(BlueprintCallable, Category = Ability)FGameplayEffectContextHandle GetGrantedByEffectContext() const;/**从我们的所有者和可选的TargetData生成GameplayEffectContextHandle。*/UFUNCTION(BlueprintCallable, Category = Ability)virtual FGameplayEffectContextHandle GetContextFromOwner(FGameplayAbilityTargetDataHandle OptionalTargetData) const;/** 根据指定的演员信息返回一个效果上下文 */virtual FGameplayEffectContextHandle MakeEffectContext(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo *ActorInfo) const;/** 便捷方法,用于技能获取传出的游戏效果规格(例如,传递给投射物,以便应用于它们击中的任何人) */UFUNCTION(BlueprintCallable, Category=Ability)FGameplayEffectSpecHandle MakeOutgoingGameplayEffectSpec(TSubclassOf<UGameplayEffect> GameplayEffectClass, float Level=1.f) const;/** 上述函数的本地版本 */virtual FGameplayEffectSpecHandle MakeOutgoingGameplayEffectSpec(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, TSubclassOf<UGameplayEffect> GameplayEffectClass, float Level = 1.f) const;/** 将技能的标签添加到给定的GameplayEffectSpec中。这可能会根据项目被重写。 */virtual void ApplyAbilityTagsToGameplayEffectSpec(FGameplayEffectSpec& Spec, FGameplayAbilitySpec* AbilitySpec) const;/** 返回技能当前是否处于激活状态 */bool IsActive() const;/** 此技能是否由TriggerData触发(或者是通过输入/游戏代码显式触发的) */bool IsTriggered() const;/** 此技能是否在预测客户端上运行,单人游戏中这是假的 */bool IsPredictingClient() const;/** 如果这是在服务器上并且正在为非本地玩家执行,则为真,单人游戏中这是假的 */bool IsForRemoteClient() const;/** 如果拥有者演员是本地控制的,则为真,在单人游戏中为真 */UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = Ability, Meta = (ExpandBoolAsExecs = "ReturnValue"))bool IsLocallyControlled() const;/** 如果这是服务器或者单人游戏,则为真 */bool HasAuthority(const FGameplayAbilityActivationInfo* ActivationInfo) const;//HasAuthority的蓝图版本UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = Ability, DisplayName = "HasAuthority", Meta = (ExpandBoolAsExecs = "ReturnValue"))bool K2_HasAuthority() const;/** 如果我们能有效的预测键并且预期会工作,则为真 */bool HasAuthorityOrPredictionKey(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo* ActivationInfo) const;/** 如果已经被实例化,则为真,对于蓝图总是为真 */bool IsInstantiated() const;/** 技能结束时的通知。通过TryActivateAbility设置。 */FOnGameplayAbilityEnded OnGameplayAbilityEnded;/** 技能以某种方式结束时的通知 */FGameplayAbilityEndedDelegate OnGameplayAbilityEndedWithData;/** 技能被取消时的通知。在OnGameplayAbilityEnded之前调用。 */FOnGameplayAbilityCancelled OnGameplayAbilityCancelled;/** 技能状态任务用来处理状态结束时的事件 */FOnGameplayAbilityStateEnded OnGameplayAbilityStateEnded;/** 当这个技能被服务器确认时的回调 */FGenericAbilityDelegate OnConfirmDelegate;// --------------------------------------// CanActivateAbility 能否激活技能// --------------------------------------/** 返回如果当前可以激活此技能,则为真。没有副作用 */virtual bool CanActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayTagContainer* SourceTags = nullptr, const FGameplayTagContainer* TargetTags = nullptr, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr) const;/** 返回如果此技能现在可以被触发,则为真。没有副作用 */virtual bool ShouldAbilityRespondToEvent(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayEventData* Payload) const;/** 返回是否应该激活此技能 */virtual bool ShouldActivateAbility(ENetRole Role) const;/** 返回当前激活的冷却时间剩余的秒数。 */UFUNCTION(BlueprintCallable, Category = Ability)float GetCooldownTimeRemaining() const;/** 返回当前激活的冷却时间剩余的秒数。 */virtual float GetCooldownTimeRemaining(const FGameplayAbilityActorInfo* ActorInfo) const;/** 返回当前激活的冷却时间剩余的秒数和此冷却的原始持续时间。 */virtual void GetCooldownTimeRemainingAndDuration(FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, float& TimeRemaining, float& CooldownDuration) const;/** 返回所有可以将此技能置入冷却的标签 */virtual const FGameplayTagContainer* GetCooldownTags() const;/** 如果技能的标签没有被封锁,并且没有“阻塞”标签,并且具有所有“必需”标签,则返回真。 */virtual bool DoesAbilitySatisfyTagRequirements(const UAbilitySystemComponent& AbilitySystemComponent, const FGameplayTagContainer* SourceTags = nullptr, const FGameplayTagContainer* TargetTags = nullptr, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr) const;/** 如果此技能正在阻止其他技能,则返回真 */virtual bool IsBlockingOtherAbilities() const;/** 设置技能阻塞标志是否启用或禁用。仅对实例化的技能有效 */UFUNCTION(BlueprintCallable, Category = Ability)virtual void SetShouldBlockOtherAbilities(bool bShouldBlockAbilities);// --------------------------------------// CancelAbility 取消技能// --------------------------------------/** 销毁每次执行时实例化的技能。每个执行对应一个实例的技能应该“重置”。任何活跃的技能状态任务都会接收到'OnAbilityStateInterrupted'事件。非实例化的技能 - 我们能做什么? */virtual void CancelAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateCancelAbility);/** 从蓝图调用以自然取消技能 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "CancelAbility", meta=(ScriptName = "CancelAbility"))void K2_CancelAbility();/** 返回此技能是否可以被取消 */virtual bool CanBeCanceled() const;/** 设置技能是否应该忽略取消请求。仅对实例化的技能有效 */UFUNCTION(BlueprintCallable, Category=Ability)virtual void SetCanBeCanceled(bool bCanBeCanceled);// --------------------------------------// CommitAbility 提交技能 的消耗和冷却// --------------------------------------/** 尝试提交技能(消耗资源等)。这是我们最后的机会来失败。覆盖ActivateAbility的子类必须自己调用这个函数! */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "CommitAbility", meta=(ScriptName = "CommitAbility"))virtual bool K2_CommitAbility();/** 仅尝试提交技能的冷却时间。如果BroadcastCommitEvent为true,它将广播提交事件,像WaitAbilityCommit这样的任务会监听这个事件。 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "CommitAbilityCooldown", meta=(ScriptName = "CommitAbilityCooldown"))virtual bool K2_CommitAbilityCooldown(bool BroadcastCommitEvent=false, bool ForceCooldown=false);/** 仅尝试提交技能的成本。如果BroadcastCommitEvent为true,它将广播提交事件,像WaitAbilityCommit这样的任务会监听这个事件。 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "CommitAbilityCost", meta=(ScriptName = "CommitAbilityCost"))virtual bool K2_CommitAbilityCost(bool BroadcastCommitEvent=false);/** 检查技能的冷却时间,但不应用它。*/UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "CheckAbilityCooldown", meta=(ScriptName = "CheckAbilityCooldown"))virtual bool K2_CheckAbilityCooldown();/** 检查技能的成本,但不应用它。 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "CheckAbilityCost", meta=(ScriptName = "CheckAbilityCost"))virtual bool K2_CheckAbilityCost();// 以下是一些虚拟函数,用于在提交技能时执行特定的检查和操作virtual bool CommitAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr);virtual bool CommitAbilityCooldown(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const bool ForceCooldown, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr);virtual bool CommitAbilityCost(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr);/** 在提交之前的最后机会失败,这通常会与CanActivateAbility相同。如果它们在CommitExecute中消耗了额外的资源,一些技能可能需要在这里进行额外的检查 */virtual bool CommitCheck(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr);/** 从蓝图调用函数CommitAbility */UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "CommitExecute", meta = (ScriptName = "CommitExecute"))void K2_CommitExecute();/** 原子性地执行提交(消耗资源、执行冷却时间等) */virtual void CommitExecute(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo);/** 返回用于确定冷却时间的游戏效果 */virtual UGameplayEffect* GetCooldownGameplayEffect() const;/** 返回用于应用成本的游戏效果 */virtual UGameplayEffect* GetCostGameplayEffect() const;/** 检查冷却时间。如果可以再次使用则返回真,否则返回假 */virtual bool CheckCooldown(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr) const;/** 将CooldownGameplayEffect应用到目标 */virtual void ApplyCooldown(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) const;/** 检查成本。如果可以支付技能则返回真,否则返回假 */virtual bool CheckCost(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr) const;/** 将技能的成本应用到目标 */virtual void ApplyCost(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) const;// --------------------------------------// Input 输入 InputPressed和InputReleased函数是虚函数,它们作为输入绑定的存根存在。在实际的游戏逻辑中,这些函数通常会被重写以响应玩家的输入事件// --------------------------------------/** 触发技能按下 */virtual void InputPressed(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) {};/** 触发技能抬起 */virtual void InputReleased(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo) {};/** 从AbilityTask_WaitConfirmCancel调用,用于处理输入确认* OnWaitingForConfirmInputBegin和OnWaitingForConfirmInputEnd函数用于处理等待确认输入的情况。这些函数可能在技能激活的确认/取消逻辑中被调用,例如在玩家需要按下按钮来确认或取消技能激活时。*/virtual void OnWaitingForConfirmInputBegin() {}virtual void OnWaitingForConfirmInputEnd() {}// --------------------------------------// Animation 动画// --------------------------------------/** 用于获取当前与技能关联的蒙太奇动画(如果有的话) */UFUNCTION(BlueprintCallable, Category = Animation)UAnimMontage* GetCurrentMontage() const;/** 设置当前的蒙太奇动画,这通常用于将蒙太奇事件与技能事件关联起来,例如在技能激活时播放特定的动画序列 */virtual void SetCurrentMontage(class UAnimMontage* InCurrentMontage);/** 设置移动同步点,但由于在Unreal Engine 5.3版本中没有实际用途,已被标记为弃用(deprecated),并计划在未来的引擎版本中移除。 */UE_DEPRECATED(5.3, "This serves no purpose and will be removed in future engine versions")virtual void SetMovementSyncPoint(FName SyncName);// ----------------------------------------------------------------------------------------------------------------// Ability Levels and source objects 技能等级和源对象// ----------------------------------------------------------------------------------------------------------------/** 获取当前技能的等级 */UFUNCTION(BlueprintCallable, Category = Ability)int32 GetAbilityLevel() const;/** 返回非实例化技能的当前等级。你必须在这些上下文中调用这个版本! */int32 GetAbilityLevel(FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo) const;/** GetAbilityLevel的蓝图版本 */UFUNCTION(BlueprintCallable, Category = Ability, meta = (DisplayName = "GetAbilityLevelNonInstanced", ReturnDisplayName = "AbilityLevel"))int32 GetAbilityLevel_BP(FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo& ActorInfo) const;/** 检索与此技能关联的SourceObject。只能在实例化的技能上调用。 */UFUNCTION(BlueprintCallable, Category = Ability)UObject* GetCurrentSourceObject() const;/** 检索与此技能关联的SourceObject。可以在非实例化的技能上调用。 */UObject* GetSourceObject(FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo) const;/** GetSourceObject的蓝图版本 */UFUNCTION(BlueprintCallable, Category = Ability, meta = (DisplayName = "GetSourceObjectNonInstanced", ReturnDisplayName = "SourceObject"))UObject* GetSourceObject_BP(FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo& ActorInfo) const;// --------------------------------------// Interaction with ability system component 与ASC的交互// --------------------------------------/** ASC调用此函数以通知此技能实例远程实例已结束 */virtual void SetRemoteInstanceHasEnded();/** 通知技能AvatarActor已被替换。如果技能依赖于avatar状态,它可能需要结束自己 */virtual void NotifyAvatarDestroyed();/** 通知技能有任务正在等待玩家执行某些操作 */virtual void NotifyAbilityTaskWaitingOnPlayerData(class UAbilityTask* AbilityTask);/** 通知技能有任务正在等待玩家的avatar在世界中执行某些操作 */virtual void NotifyAbilityTaskWaitingOnAvatar(class UAbilityTask* AbilityTask);/** 当技能被赋予ASC时调用 */virtual void OnGiveAbility(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec);/** 当技能从ASC中移除时调用 */virtual void OnRemoveAbility(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec) {}/** 当avatar actor被设置/更改时调用 */virtual void OnAvatarSet(const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilitySpec& Spec);/** 它接收技能规格(ability spec),并检查是否应该允许该技能规格上的复制。这不会阻止技能UObject本身的复制,而只是阻止位于UAbilitySystemComponent的ActivatableAbilities内部针对这个技能的规格复制。 */virtual bool ShouldReplicateAbilitySpec(const FGameplayAbilitySpec& AbilitySpec) const{return true;}/** * 使当前预测键无效。这应该用在有有效预测窗口的情况下,但服务器正在执行只有它能做的逻辑,之后执行客户端本来可以预测的动作(如果客户端能够先运行服务器独有的代码)。* 这个函数会立即返回,除了清除当前预测键之外没有其他副作用。*/ UFUNCTION(BlueprintCallable, Category = Ability)void InvalidateClientPredictionKey() const;/** 移除授予此技能的GameplayEffect。只能在实例化的技能上调用 */UFUNCTION(BlueprintCallable, Category = Ability)virtual void RemoveGrantedByEffect();/** 向用户添加一个调试消息 */void AddAbilityTaskDebugMessage(UGameplayTask* AbilityTask, FString DebugMessage);// --------------------------------------// 公共变量,为了向后兼容性而暴露 // --------------------------------------/** 这个技能有这些标签 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="AbilityTagCategory"))FGameplayTagContainer AbilityTags;/** 如果为真,这个技能将总是将输入按下/释放事件复制到服务器。 */UPROPERTY(EditDefaultsOnly, Category = Input)bool bReplicateInputDirectly;/** 当这个技能的远程实例结束时设置(但本地实例可能仍在运行或完成中) */UPROPERTY()bool RemoteInstanceEnded;// --------------------------------------// 覆写 UObject 成员函数// -------------------------------------- virtual UWorld* GetWorld() const override;virtual int32 GetFunctionCallspace(UFunction* Function, FFrame* Stack) override;virtual bool CallRemoteFunction(UFunction* Function, void* Parameters, FOutParmRec* OutParms, FFrame* Stack) override;virtual bool IsSupportedForNetworking() const override;#if UE_WITH_IRIS/** Register all replication fragments */virtual void RegisterReplicationFragments(UE::Net::FFragmentRegistrationContext& Context, UE::Net::EFragmentRegistrationFlags RegistrationFlags) override;
#endif // UE_WITH_IRIS// --------------------------------------// IGameplayTaskOwnerInterface// -------------------------------------- virtual UGameplayTasksComponent* GetGameplayTasksComponent(const UGameplayTask& Task) const override;virtual AActor* GetGameplayTaskOwner(const UGameplayTask* Task) const override;virtual AActor* GetGameplayTaskAvatar(const UGameplayTask* Task) const override;virtual void OnGameplayTaskInitialized(UGameplayTask& Task) override;virtual void OnGameplayTaskActivated(UGameplayTask& Task) override;virtual void OnGameplayTaskDeactivated(UGameplayTask& Task) override;protected:// --------------------------------------// ShouldAbilityRespondToEvent// --------------------------------------/** 如果这个技能现在可以被激活,则返回true。没有副作用,蓝图可调用 */UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "ShouldAbilityRespondToEvent", meta=(ScriptName = "ShouldAbilityRespondToEvent"))bool K2_ShouldAbilityRespondToEvent(FGameplayAbilityActorInfo ActorInfo, FGameplayEventData Payload) const;/** 一个标志,表示是否在蓝图(Blueprint)中实现了 ShouldAbilityRespondToEvent 事件 */ bool bHasBlueprintShouldAbilityRespondToEvent;/** 发送一个游戏事件,并创建一个预测窗口 */UFUNCTION(BlueprintCallable, Category = Ability)virtual void SendGameplayEvent(FGameplayTag EventTag, FGameplayEventData Payload);// --------------------------------------// CanActivate// --------------------------------------/** 如果当前可以激活这个技能,则返回true。这个函数没有副作用。 */UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName="CanActivateAbility", meta=(ScriptName="CanActivateAbility"))bool K2_CanActivateAbility(FGameplayAbilityActorInfo ActorInfo, const FGameplayAbilitySpecHandle Handle, FGameplayTagContainer& RelevantTags) const;//其用途可能是在类的其他部分或蓝图中追踪是否有一个蓝图实现了CanActivateAbility事件。这样,你可以根据这个标志来决定是否调用蓝图中的实现或默认的C++实现。bool bHasBlueprintCanUse;// --------------------------------------// ActivateAbility 激活技能// --------------------------------------/*** 定义技能主要功能的功能。* -子类可以覆盖此类的实现* -函数实现需要调用CommitAbility* -函数实现需要调用EndAbility* * 在这个图中允许使用延迟/异步动作。注意,Commit和EndAbility调用要求适用于K2_ActivateAbility图。* 在C++中,调用K2_ActivateAbility()可能会在没有调用CommitAbility或EndAbility的情况下返回。* 但是预计这只会在有延迟/异步动作待处理时发生。当K2_ActivateAbility逻辑上完成时,我们预期Commit/End已经被调用。* */UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "ActivateAbility", meta=(ScriptName = "ActivateAbility"))void K2_ActivateAbility();UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "ActivateAbilityFromEvent", meta=(ScriptName = "ActivateAbilityFromEvent"))void K2_ActivateAbilityFromEvent(const FGameplayEventData& EventData);bool bHasBlueprintActivate;bool bHasBlueprintActivateFromEvent;/** 实际激活技能,不要直接调用这个函数 */virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData);/** 执行初始化工作,然后调用ActivateAbility */virtual void PreActivate(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, FOnGameplayAbilityEnded::FDelegate* OnGameplayAbilityEndedDelegate, const FGameplayEventData* TriggerEventData = nullptr);/** 执行PreActivate和ActivateAbility */void CallActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, FOnGameplayAbilityEnded::FDelegate* OnGameplayAbilityEndedDelegate = nullptr, const FGameplayEventData* TriggerEventData = nullptr);/** 当服务器确认其执行时,对预测技能调用 */virtual void ConfirmActivateSucceed();// -------------------------------------// EndAbility 结束技能// -------------------------------------/** 从蓝图调用以强制结束技能,而不取消它。这将会复制结束技能到客户端或服务器,可以中断任务 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName="End Ability", meta=(ScriptName = "EndAbility"))virtual void K2_EndAbility();/** 从蓝图调用以自然结束技能。这只会在本地结束预测的技能,允许它在客户端或服务器上自然结束 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "End Ability Locally", meta = (ScriptName = "EndAbilityLocally"))virtual void K2_EndAbilityLocally();/** 蓝图事件,如果技能正常或异常结束将被调用 */UFUNCTION(BlueprintImplementableEvent, Category = Ability, DisplayName = "OnEndAbility", meta=(ScriptName = "OnEndAbility"))void K2_OnEndAbility(bool bWasCancelled);/** 检查技能是否可以结束 */bool IsEndAbilityValid(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo) const;/** 原生函数,如果技能正常或异常结束将被调用。如果bReplicate设置为true,尝试将结束复制到客户端/服务器 */virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled);// -------------------------------------// Apply Gameplay effects to Self 应用游戏效果到自身// -------------------------------------/** 将一个游戏效果应用到这个技能的拥有者上 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName="ApplyGameplayEffectToOwner", meta=(ScriptName="ApplyGameplayEffectToOwner"))FActiveGameplayEffectHandle BP_ApplyGameplayEffectToOwner(TSubclassOf<UGameplayEffect> GameplayEffectClass, int32 GameplayEffectLevel = 1, int32 Stacks = 1);/** 不能从蓝图调用,可以安全地在CDO/非实例化技能上调用 */FActiveGameplayEffectHandle ApplyGameplayEffectToOwner(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const UGameplayEffect* GameplayEffect, float GameplayEffectLevel, int32 Stacks = 1) const;/** 将之前创建的游戏效果规格应用到这个技能的拥有者上 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "ApplyGameplayEffectSpecToOwner", meta=(ScriptName = "ApplyGameplayEffectSpecToOwner"))FActiveGameplayEffectHandle K2_ApplyGameplayEffectSpecToOwner(const FGameplayEffectSpecHandle EffectSpecHandle);FActiveGameplayEffectHandle ApplyGameplayEffectSpecToOwner(const FGameplayAbilitySpecHandle AbilityHandle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEffectSpecHandle SpecHandle) const;// -------------------------------------// Apply Gameplay effects to Target 应用GE到目标// -------------------------------------/** 将一个游戏效果应用到目标 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "ApplyGameplayEffectToTarget", meta=(ScriptName = "ApplyGameplayEffectToTarget"))TArray<FActiveGameplayEffectHandle> BP_ApplyGameplayEffectToTarget(FGameplayAbilityTargetDataHandle TargetData, TSubclassOf<UGameplayEffect> GameplayEffectClass, int32 GameplayEffectLevel = 1, int32 Stacks = 1);/** 不能从蓝图调用,可以安全地在CDO/非实例化技能上调用 */TArray<FActiveGameplayEffectHandle> ApplyGameplayEffectToTarget(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayAbilityTargetDataHandle& Target, TSubclassOf<UGameplayEffect> GameplayEffectClass, float GameplayEffectLevel, int32 Stacks = 1) const;/** 将之前创建的游戏效果规格应用到目标 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "ApplyGameplayEffectSpecToTarget", meta=(ScriptName = "ApplyGameplayEffectSpecToTarget"))TArray<FActiveGameplayEffectHandle> K2_ApplyGameplayEffectSpecToTarget(const FGameplayEffectSpecHandle EffectSpecHandle, FGameplayAbilityTargetDataHandle TargetData);TArray<FActiveGameplayEffectHandle> ApplyGameplayEffectSpecToTarget(const FGameplayAbilitySpecHandle AbilityHandle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEffectSpecHandle SpecHandle, const FGameplayAbilityTargetDataHandle& TargetData) const;// -------------------------------------// Remove Gameplay effects from Self 从自身移除效果// -------------------------------------/** 移除拥有者上与给定资产等级标签匹配的游戏效果 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName="RemoveGameplayEffectFromOwnerWithAssetTags", meta=(ScriptName="RemoveGameplayEffectFromOwnerWithAssetTags"))void BP_RemoveGameplayEffectFromOwnerWithAssetTags(FGameplayTagContainer WithAssetTags, int32 StacksToRemove = -1);/** 用于移除拥有者上授予的、与特定标签容器匹配的游戏效果 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName="RemoveGameplayEffectFromOwnerWithGrantedTags", meta=(ScriptName="RemoveGameplayEffectFromOwnerWithGrantedTags"))void BP_RemoveGameplayEffectFromOwnerWithGrantedTags(FGameplayTagContainer WithGrantedTags, int32 StacksToRemove = -1);/** 允许从蓝图中调用,用于移除与特定FActiveGameplayEffectHandle句柄匹配的游戏效果。 */UFUNCTION(BlueprintCallable, Category = Ability, DisplayName = "RemoveGameplayEffectFromOwnerWithHandle", meta=(ScriptName = "RemoveGameplayEffectFromOwnerWithHandle"))void BP_RemoveGameplayEffectFromOwnerWithHandle(FActiveGameplayEffectHandle Handle, int32 StacksToRemove = -1);// -------------------------------------// GameplayCue 游戏提示效果// 技能可以在不创建GE的情况下调用GC// -------------------------------------/** 在技能拥有者上触发一个游戏提示 */UFUNCTION(BlueprintCallable, Category = Ability, meta=(GameplayTagFilter="GameplayCue"), DisplayName="Execute GameplayCue On Owner", meta=(ScriptName="ExecuteGameplayCue"))virtual void K2_ExecuteGameplayCue(FGameplayTag GameplayCueTag, FGameplayEffectContextHandle Context);/** 在技能拥有者上触发一个带有额外参数的游戏提示 */UFUNCTION(BlueprintCallable, Category = Ability, meta = (GameplayTagFilter = "GameplayCue"), DisplayName = "Execute GameplayCueWithParams On Owner", meta=(ScriptName = "ExecuteGameplayCueWithParams"))virtual void K2_ExecuteGameplayCueWithParams(FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameters);/** 向技能拥有者添加一个持久的游戏提示。可选地,如果技能结束,则移除 */UFUNCTION(BlueprintCallable, Category = Ability, meta=(GameplayTagFilter="GameplayCue"), DisplayName="Add GameplayCue To Owner", meta=(ScriptName="AddGameplayCue"))virtual void K2_AddGameplayCue(FGameplayTag GameplayCueTag, FGameplayEffectContextHandle Context, bool bRemoveOnAbilityEnd = true);/** 向技能拥有者添加一个持久的游戏提示。可选地,如果技能结束,则移除 */UFUNCTION(BlueprintCallable, Category = Ability, meta = (GameplayTagFilter = "GameplayCue"), DisplayName = "Add GameplayCueWithParams To Owner", meta=(ScriptName = "AddGameplayCueWithParams"))virtual void K2_AddGameplayCueWithParams(FGameplayTag GameplayCueTag, const FGameplayCueParameters& GameplayCueParameter, bool bRemoveOnAbilityEnd = true);/** 从技能拥有者移除一个持久的游戏提示 */UFUNCTION(BlueprintCallable, Category = Ability, meta=(GameplayTagFilter="GameplayCue"), DisplayName="Remove GameplayCue From Owner", meta=(ScriptName="RemoveGameplayCue"))virtual void K2_RemoveGameplayCue(FGameplayTag GameplayCueTag);// -------------------------------------// Protected properties 受保护的属性,这些属性用于控制技能在网络上的复制、实例化策略以及消耗和冷却类的设置。这些数值可以在蓝图中设置。// -------------------------------------/** 技能如何在网络上复制状态/事件给每个人。对于NetExecutionPolicy不需要复制。 */UPROPERTY(EditDefaultsOnly, Category = Advanced)TEnumAsByte<EGameplayAbilityReplicationPolicy::Type> ReplicationPolicy;/** 技能在执行时是如何实例化的。这限制了技能在其实现中可以执行的操作。 */UPROPERTY(EditDefaultsOnly, Category = Advanced)TEnumAsByte<EGameplayAbilityInstancingPolicy::Type> InstancingPolicy;/** 如果设置了,技能服务器端版本可以被客户端版本取消。客户端版本总是可以被服务器取消。 */UPROPERTY(EditDefaultsOnly, Category = Advanced)bool bServerRespectsRemoteAbilityCancellation;/** 如果为true,并且尝试激活一个已经激活的实例化技能,结束它并重新触发它。 */UPROPERTY(EditDefaultsOnly, Category = Advanced)bool bRetriggerInstancedAbility;/** 这是特定于技能实例的信息。例如,它是否在预测、授权、确认等。 */UPROPERTY(BlueprintReadOnly, Category = Ability)FGameplayAbilityActivationInfo CurrentActivationInfo;/** 如果是通过事件激活的技能,这是特定于此技能实例的信息 */UPROPERTY(BlueprintReadOnly, Category = Ability)FGameplayEventData CurrentEventData;/** 技能在网络上是如何执行的。客户端是“询问并预测”、“询问并等待”还是“不问(直接执行)”。 */UPROPERTY(EditDefaultsOnly, Category=Advanced)TEnumAsByte<EGameplayAbilityNetExecutionPolicy::Type> NetExecutionPolicy;/** 这个技能有哪些保护措施?客户端是否被允许请求更改技能的执行? */UPROPERTY(EditDefaultsOnly, Category = Advanced)TEnumAsByte<EGameplayAbilityNetSecurityPolicy::Type> NetSecurityPolicy;/** 这个GameplayEffect代表了技能的成本(法力、耐力等)。当技能被提交时,它将被应用。 */UPROPERTY(EditDefaultsOnly, Category = Costs)TSubclassOf<class UGameplayEffect> CostGameplayEffectClass;/** 触发器,用于确定这个技能是否应该响应事件执行 */UPROPERTY(EditDefaultsOnly, Category = Triggers)TArray<FAbilityTriggerData> AbilityTriggers;/** 这个GameplayEffect代表了冷却时间。当技能被提交时,它将被应用,并且技能在过期前不能再次使用。 */UPROPERTY(EditDefaultsOnly, Category = Cooldowns)TSubclassOf<class UGameplayEffect> CooldownGameplayEffectClass;// ----------------------------------------------------------------------------------------------------------------// Ability exclusion / canceling 技能 排除/取消 当前参数可以在蓝图中设置// ----------------------------------------------------------------------------------------------------------------/** 当这个技能被执行时,带有这些标签的技能将被取消。 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="AbilityTagCategory"))FGameplayTagContainer CancelAbilitiesWithTag;/** 当这个技能处于激活状态时,带有这些标签的技能将被阻止 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="AbilityTagCategory"))FGameplayTagContainer BlockAbilitiesWithTag;/** 当这个技能激活时,要应用到激活所有者上的标签。如果AbilitySystemGlobals中启用了ReplicateActivationOwnedTags,则这些标签会被复制 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="OwnedTagsCategory"))FGameplayTagContainer ActivationOwnedTags;/** 只有当激活的演员/组件具有所有这些标签时,这个技能才能被激活 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="OwnedTagsCategory"))FGameplayTagContainer ActivationRequiredTags;/** 如果激活的演员/组件具有这些标签中的任何一个,这个技能将被阻止 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="OwnedTagsCategory"))FGameplayTagContainer ActivationBlockedTags;/** 只有当源演员/组件具有所有这些标签时,这个技能才能被激活 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="SourceTagsCategory"))FGameplayTagContainer SourceRequiredTags;/** 如果源演员/组件具有这些标签中的任何一个,这个技能将被阻止 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="SourceTagsCategory"))FGameplayTagContainer SourceBlockedTags;/** 只有当目标演员/组件具有所有这些标签时,这个技能才能被激活 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="TargetTagsCategory"))FGameplayTagContainer TargetRequiredTags;/** 如果目标演员/组件具有这些标签中的任何一个,这个技能将被阻止 */UPROPERTY(EditDefaultsOnly, Category = Tags, meta=(Categories="TargetTagsCategory"))FGameplayTagContainer TargetBlockedTags;// ----------------------------------------------------------------------------------------------------------------// Ability Tasks 技能任务// ----------------------------------------------------------------------------------------------------------------/** 查找所有当前激活的、名为InstanceName的任务,并确认它们。具体含义取决于个别任务。如果bEndTask为true,默认情况下除了结束之外不做其他操作。 */UFUNCTION(BlueprintCallable, Category = Ability)void ConfirmTaskByInstanceName(FName InstanceName, bool bEndTask);/** 内部函数,取消上一次我们要求取消的所有任务(按实例名称)。 */void EndOrCancelTasksByInstanceName();TArray<FName> CancelTaskInstanceNames;/** 将任何具有此实例名称的任务添加到下一个帧将被结束(而不是取消)的列表中。另见CancelTaskByInstanceName。 */UFUNCTION(BlueprintCallable, Category = Ability)void EndTaskByInstanceName(FName InstanceName);TArray<FName> EndTaskInstanceNames;/** 将任何具有此实例名称的任务添加到下一个帧将被取消(而不是结束)的列表中。另见EndTaskByInstanceName。 */UFUNCTION(BlueprintCallable, Category = Ability)void CancelTaskByInstanceName(FName InstanceName);/** 结束任何具有给定名称的活跃技能状态任务。如果名称为'None',则结束所有活跃状态(以任意顺序)。 */UFUNCTION(BlueprintCallable, Category = Ability)void EndAbilityState(FName OptionalStateNameToEnd);/** 当前活跃任务的列表,不要直接修改 */UPROPERTY()TArray<TObjectPtr<UGameplayTask>> ActiveTasks;/** 任务可以在它们的生命周期中发出调试消息以供调试目的。保存在技能上,以便在任务完成后仍然存在 */TArray<FAbilityTaskDebugMessage> TaskDebugMessages;// ----------------------------------------------------------------------------------------------------------------// Animation 动画// ----------------------------------------------------------------------------------------------------------------/** 立即将活动蒙太奇跳转到指定的部分 */UFUNCTION(BlueprintCallable, Category="Ability|Animation")void MontageJumpToSection(FName SectionName);/** 设置活动蒙太奇的下一个部分名称 */UFUNCTION(BlueprintCallable, Category = "Ability|Animation")void MontageSetNextSectionName(FName FromSectionName, FName ToSectionName);/*** 停止当前的动画蒙太奇。** @param OverrideBlendTime 如果大于或等于0,将覆盖AnimMontage实例上的BlendOutTime参数*/UFUNCTION(BlueprintCallable, Category="Ability|Animation", Meta = (AdvancedDisplay = "OverrideBlendOutTime"))void MontageStop(float OverrideBlendOutTime = -1.0f);/** 此技能正在播放的活动蒙太奇 */UPROPERTY()TObjectPtr<class UAnimMontage> CurrentMontage;// ----------------------------------------------------------------------------------------------------------------// Target Data 目标数据// ----------------------------------------------------------------------------------------------------------------/** 从拥有者avatar的位置创建一个目标位置 */UFUNCTION(BlueprintPure, Category = Ability)FGameplayAbilityTargetingLocationInfo MakeTargetLocationInfoFromOwnerActor();/** 从拥有者avatar的骨骼网格组件上的插座创建一个目标位置 */UFUNCTION(BlueprintPure, Category = Ability)FGameplayAbilityTargetingLocationInfo MakeTargetLocationInfoFromOwnerSkeletalMeshComponent(FName SocketName);// ----------------------------------------------------------------------------------------------------------------// Setters for temporary execution data 临时执行数据的设置函数// ----------------------------------------------------------------------------------------------------------------/** 在由于复制而被创建后,被调用以进行初始化 */virtual void PostNetInit();/** 修改actor信息,仅在实例化的技能上是安全的 */virtual void SetCurrentActorInfo(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo) const;/** 修改激活信息,仅在实例化的技能上是安全的 */virtual void SetCurrentActivationInfo(const FGameplayAbilityActivationInfo ActivationInfo);/** 设置actor和激活信息 */void SetCurrentInfo(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo);/** * 这是关于使用我们的实体的共享、缓存信息* E.g, Actor*, MovementComponent*, AnimInstance, etc.* 希望每个actor分配一次并由多个技能共享。* 实际的结构可能根据游戏需要被覆盖以包含特定于游戏的数据。* (例如,子类可能希望将其转换为FMyGameAbilityActorInfo)CurrentActorInfo是一个可变的指针,指向当前使用技能的实体的信息,例如角色、移动组件或动画实例。这个信息被缓存并共享,以减少重复的内存分配。*/mutable const FGameplayAbilityActorInfo* CurrentActorInfo;/** 用于实例化的技能的规格句柄 */mutable FGameplayAbilitySpecHandle CurrentSpecHandle;/** 在这个技能期间添加的游戏提示,当技能结束时将自动移除 */TSet<FGameplayTag> TrackedGameplayCues;/** 如果技能当前处于激活状态,则为真。对于每个所有者实例化的技能 */UPROPERTY()bool bIsActive;/** 如果结束技能已被调用,但尚未完成,则为真。 */UPROPERTY()bool bIsAbilityEnding = false;/** 如果技能当前可以被取消,则为真,否则只会通过EndAbility调用被取消。 */UPROPERTY()bool bIsCancelable;/** 否当前正在阻止其他技能的激活 */UPROPERTY()bool bIsBlockingOtherAbilities;/** 所有当前作用域锁的计数。用于管理技能的作用域锁定,防止在技能执行期间并行执行其他操作。 */mutable int8 ScopeLockCount;/** 等待作用域锁结束以便运行的所有函数的列表。包含所有等待作用域锁结束以便执行的委托函数 */mutable TArray<FPostLockDelegate> WaitingToExecute;/** 增加作用域锁计数。 */void IncrementListLock() const;/** 减少作用域锁计数。如果计数降至零,则运行等待执行的委托。 */void DecrementListLock() const;public:/** 当这个标志被设置时,它表示在技能结束时,应该将该技能标记为待删除。 */void SetMarkPendingKillOnAbilityEnd(bool bInMarkPendingKillOnAbilityEnd) { bMarkPendingKillOnAbilityEnd = bInMarkPendingKillOnAbilityEnd; }/** 用于查询bMarkPendingKillOnAbilityEnd标志是否已经被设置。如果返回true,则表示该技能在结束时将被标记为待删除。 */bool IsMarkPendingKillOnAbilityEnd() const { return bMarkPendingKillOnAbilityEnd; }protected:/**由AbilitySystemComponent::OnRemoveAbility方法设置。当这个方法被调用时,它将这个标志设置为true,以指示在AbilitySystemComponent::NotifyAbilityEnded事件被触发时,该技能需要被清理。 */UPROPERTY(BlueprintReadOnly, Category = Ability)bool bMarkPendingKillOnAbilityEnd;
};
在源码中,我可以看到技能的简介,以及内置的一些函数属性,并且可以看到在技能蓝图中设置的属性在代码里面是如何设置的。
里面带有注释,介绍了技能的功能:
- 支持使用技能冷却时间,以及资源消耗(法力,体力等)
- 支持客户端和服务端的复制,预测功能
- 实例化,支持非实例化(本地)每个所有者实例化,每次执行都实例化(默认)
- 输入绑定技能激活,应用技能。
- 支持Task,通过Task可以在技能内部实现异步处理。
我们实现的技能相当于是一个类,它可以直接被使用,或者实例化以后使用它的实例。
里面有一些常用的函数:
- CanActivateAbility() - 判断技能是否可以被激活
- TryActivateAbility() - 尝试激活技能
- CallActivateAbility() - 做一些激活前的工作,然后调用ActivateAbility()
- ActivateAbility() - 激活技能事件回调,在技能激活后,可以实现自定义逻辑,推荐在子类中覆盖。
- CommitAbility() - 提交资源/冷却时间等。ActivateAbility()必须调用这个函数!
- CancelAbility() - 从外部取消函数
- EndAbility() - 这个函数是自身调用技能结束。