UE5 GameplayAbility 源码定义解析

这一篇文章主要是对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;
};

在源码中,我可以看到技能的简介,以及内置的一些函数属性,并且可以看到在技能蓝图中设置的属性在代码里面是如何设置的。
里面带有注释,介绍了技能的功能:

  1. 支持使用技能冷却时间,以及资源消耗(法力,体力等)
  2. 支持客户端和服务端的复制,预测功能
  3. 实例化,支持非实例化(本地)每个所有者实例化,每次执行都实例化(默认)
  4. 输入绑定技能激活,应用技能。
  5. 支持Task,通过Task可以在技能内部实现异步处理。

我们实现的技能相当于是一个类,它可以直接被使用,或者实例化以后使用它的实例。
里面有一些常用的函数:

  • CanActivateAbility() - 判断技能是否可以被激活
  • TryActivateAbility() - 尝试激活技能
  • CallActivateAbility() - 做一些激活前的工作,然后调用ActivateAbility()
  • ActivateAbility() - 激活技能事件回调,在技能激活后,可以实现自定义逻辑,推荐在子类中覆盖。
  • CommitAbility() - 提交资源/冷却时间等。ActivateAbility()必须调用这个函数!
  • CancelAbility() - 从外部取消函数
  • EndAbility() - 这个函数是自身调用技能结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/824219.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从日志读取关键数据,按照相关日期进行数据分析

分析靠近后向挡墙的距离 import os import re import sys import matplotlib.pyplot as plt from datetime import datetimedef process_distance_data(file_path):distances []timestamps []try:with open(file_path, r, encodingutf-8, errorsignore) as file:for line in…

飞行机器人专栏(十四)-- Kinect DK 人体骨骼点运动提取方法

系列文章目录 Ubuntu 18.04/20.04 CV环境配置&#xff08;下&#xff09;--手势识别TRTposeKinect DK人体骨骼识别_ubuntu kinect骨骼测试-CSDN博客文章浏览阅读1.3k次。trt_pose_ros kinect实现手势识别和人体骨骼识别&#xff0c;用于机器人运动控制参考_ubuntu kinect骨骼测…

Postgresql源码(126)TupleStore使用场景与原理分析

相关 《Postgresql源码&#xff08;125&#xff09;游标恢复执行的原理分析》 《Postgresql游标使用介绍&#xff08;cursor&#xff09;》 总结 开源PG中使用tuple store来缓存tuple集&#xff0c;默认使用work_mem空间存放&#xff0c;超过可以落盘。在PL的returns setof场景…

Pascal VOC(VOC 2012、VOC 2007) 数据集的简介

一、数据集介绍 PascalVOC(2005~2012)数据集是PASCAL VOC挑战官方使用的数据集。该数据集包含20类的物体。每张图片都有标注&#xff0c;标注的物体包括人、动物&#xff08;如猫、狗、岛等&#xff09;、交通工具&#xff08;如车、船飞机等&#xff09;、家具&#xff08;如椅…

Redux极客园项目初始化搭建

基本结构搭建 实现步骤 在 Login/index.js 中创建登录页面基本结构在 Login 目录中创建 index.scss 文件&#xff0c;指定组件样式将 logo.png 和 login.png 拷贝到 assets 目录中 代码实现 pages/Login/index.js import ./index.scss import { Card, Form, Input, Button }…

【LLM】认识LLM

文章目录 1.LLM1.1 LLM简介1.2 LLM发展1.3 市面常见的LLM1.4 LLM涌现的能力 2.RAG2.1 RAG简介2.2 RAG 的工作流程2.3 RAG 和 Finetune 对比2.4 RAG的使用场景分析 3. LangChain3.1 LangChain简介3.2 LangChain的核心组件3.3 LangChain 入门 4.开发 RAG 应用的整体流程5. 环境配…

【HBase】HBase深度解析:特性、实战应用及核心流程全景

HBase 是一个开源的、非关系型的分布式数据库&#xff08;NoSQL&#xff09;&#xff0c;它建立在 Hadoop 文件系统&#xff08;HDFS&#xff09;之上。HBase 旨在存储海量的稀疏数据集&#xff0c;这种数据集通常是由用户界面事件、消息系统、传感器设备等产生的时间序列数据。…

GPT状态和原理 - 解密OpenAI模型训练

目录 1 如何训练 GPT 助手 1.1 第一阶段 Pretraining 预训练 1.2 第二阶段&#xff1a;Supervised Finetuning有监督微调 1.3 第三阶段 Reward Modeling 奖励建模 1.4 第四阶段 Reinforcement Learning 强化学习 1.5 总结 2 第二部分&#xff1a;如何有效的应用在您的应…

mapreduce中的MapTask工作机制(Hadoop)

MapTask工作机制 MapReduce中的Map任务是整个计算过程的第一阶段&#xff0c;其主要工作是将输入数据分片并进行处理&#xff0c;生成中间键值对&#xff0c;为后续的Shuffle和Sort阶段做准备。 1. 输入数据的划分&#xff1a; 输入数据通常存储在分布式文件系统&#xff08;…

Go中的HTTP请求处理概述

使用 Go 处理 HTTP 请求主要涉及两件事&#xff1a;ServeMuxes 和 Handlers。 ServeMux本质上是一个 HTTP 请求路由器&#xff08;或多路复用器&#xff09;。它将传入的请求与预定义的 URL 路径列表进行比较&#xff0c;并在找到匹配时调用路径的关联 handler。 handler 负责写…

原生实现ajax

1 什么是ajax AJAX Asynchronous JavaScript and XML&#xff08;异步的 JavaScript 和 XML&#xff09;。 AJAX 不是新的编程语言&#xff0c;而是一种使用现有标准的新方法。 AJAX 最大的优点是在不重新加载整个页面的情况下&#xff0c;可以与服务器交换数据并更新部分网…

unity学习(85)——同步节奏(tcp架构确实有问题)

挂的时间长了&#xff0c;就出现其他下线本地不destroy的情况了&#xff0c;而且此时再登录&#xff0c;新渲染中已经没有已经下线的玩家 unity这边就没有收到126&#xff01;&#xff01;&#xff01;125的问题是多种多样的&#xff01;&#xff01;&#xff01; 化简服务器w…

设计循环队列(队列oj)

1.设计循环队列 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。 循环队列的一个好处是我们可以利用这个队列之前用过的空间。…

网站结构规范对于独立站的重要性

网站结构是指通过优化网站的内部结构和布局&#xff0c;以提高其在搜索引擎结果页面&#xff08;SERP&#xff09;中的排名和可见性的过程。 涉及到网站内部链接、导航菜单、网站url路径、网站地图等细节。 网站结构的优化可以更好地帮助搜索引擎了索引网站的内容&#xff0c…

【笔记】vscode debug进入site-packages包源码

选择左侧栏第三个图标&#xff0c;点击创建 launch.json 文件 选择 Python Debugger 选择Python文件 这里可以看到launch.json 文件 在configurations中添加键值对 "justMyCode": false在文件中打上断点&#xff0c;点击"三角符"号开始调试 按F11或者红框…

reportlab 生成pdf文件 (python)

1 安装 pip install reportlab2 应用场景 通过网页动态生成PDF文档大量的报告和数据发布用XML一步生成PDF 官网案例 3 PLATYPUS Platypus是“Page Layout and Typography Using Scripts”&#xff0c;是使用脚本的页面布局和印刷术的缩写&#xff0c;这是一个高层次页面布局…

【面试题】MySQL 事务的四大特性说一下?

事务是一个或多个 SQL 语句组成的一个执行单元&#xff0c;这些 SQL 语句要么全部执行成功&#xff0c;要么全部不执行&#xff0c;不会出现部分执行的情况。事务是数据库管理系统执行过程中的一个逻辑单位&#xff0c;由一个有限的数据库操作序列构成。 事务的主要作用是保证数…

Golang最快的Web框架

一、概述 Fiber是在Go最快的HTTP引擎Fasthttp之上构建的Go web框架。它的设计目的是在考虑到零内存分配和性能的情况下简化快速开发。它的特性&#xff1a; 稳健的路由提供静态文件极致性能内存占用空间低API终点中间件和Next支持快速服务器端编程模板引擎WebSocket支持Socke…

记一次kafkakerberos认证问题

1&#xff0c;报错信息 排查思路&#xff1a;检查kerberos配置文件 kerberos.kafka.principalkafka/huawe_baseSECURITY.COM kerberos.kafka.keytabPath/etc/huawe_base.keytab kerberos.kafka.krb5ConfPath/etc/krb5.conf但是查看kafka_client_jass.conf文件&#xff0c;发现…

网络基础-TCP/IP和OSI协议模型

一、OSI和TCP/IP模型 二、OSI七层模型 三、TCP/IP模型 参考&#xff1a;https://www.cnblogs.com/f-ck-need-u/p/7623252.html