虚幻GameAbilitySystem源码与设计解析-GameEffect的实现

/**
 * UGameplayEffect
 *  游戏玩法效果的定义。这是在编辑器中定义的数据资产,驱动着一切。
 *  它仅支持蓝图化,用于模板化游戏玩法效果。游戏玩法效果不应包含蓝图图表。
 */

UCLASS(Blueprintable, PrioritizeCategories="Status Duration GameplayEffect GameplayCues Stacking", meta = (ShortTooltip = "游戏玩法效果用于修改属性和标签。"))
class GAMEPLAYABILITIES_API UGameplayEffect : public UObject, public IGameplayTagAssetInterface
{

public:
    GENERATED_UCLASS_BODY()
    // 这些已弃用,但为了向后兼容保留,请使用 FGameplayEffectConstants:: 代替。
    static const float INFINITE_DURATION;
    static const float INSTANT_APPLICATION;
    static const float NO_PERIOD;    
    static const float INVALID_LEVEL;

    UE_DEPRECATED(5.3, "实现和方法名不匹配。使用 GetGrantedTags() 获取此游戏玩法效果应用到的 Actor 所获得的标签。")
    virtual void GetOwnedGameplayTags(FGameplayTagContainer& TagContainer) const override;

    UE_DEPRECATED(5.3, "实现和方法名不匹配。使用 GetGrantedTags().HasTag() 检查此游戏玩法效果将授予 Actor 的标签。")
    virtual bool HasMatchingGameplayTag(FGameplayTag TagToCheck) const override;

    UE_DEPRECATED(5.3, "实现和方法名不匹配。使用 GetGrantedTags().HasAll() 检查此游戏玩法效果将授予 Actor 的标签。")
    virtual bool HasAllMatchingGameplayTags(const FGameplayTagContainer& TagContainer) const override;

    UE_DEPRECATED(5.3, "实现和方法名不匹配。使用 GetGrantedTags().HasAny() 检查此游戏玩法效果将授予 Actor 的标签。")
    virtual bool HasAnyMatchingGameplayTags(const FGameplayTagContainer& TagContainer) const override;

    virtual void GetBlockedAbilityTags(FGameplayTagContainer& OutTagContainer) const;

    /** 需要正确禁用从其父类继承版本值。 */
    virtual void PostInitProperties() override;

    /** 资产加载完成后会调用一次 PostLoad。蓝图重新编译时不会再次调用(参见 PostCDOCompiled) */
    virtual void PostLoad() override;

    /** 当游戏玩法效果加载完成时调用。用于捕获 PostLoad(初始加载)和 PostCDOCompiled(后续更改) */
    virtual void OnGameplayEffectChanged();

#if WITH_EDITOR
    /** 在 PostCDOCompiled 中进行升级操作 */
    virtual void PostCDOCompiled(const FPostCDOCompiledContext& Context) override;

    /** 我们需要手动修复所有子对象,因为引擎不完全支持此操作 */
    void PostCDOCompiledFixupSubobjects();

    virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif

    /** 检查是否有任何错误 */
    UE_DEPRECATED(5.3, "此功能从未实现。现在正确的做法是使用 IsDataValid")
    void ValidateGameplayEffect() {}
为了保持兼容性的代码,没屁用

 

    /**
     * 我们能否应用此游戏玩法效果?注意:应用是添加到活动容器或执行它的通用术语。
     */
    bool CanApply(const FActiveGameplayEffectsContainer& ActiveGEContainer, const FGameplayEffectSpec& GESpec) const;

    /**
     * 收到此GE已添加到活动容器的通知。ActiveGE 将是此GE的活动版本。
     * 如果此GE应处于活动状态则返回 true(否则返回 false 以抑制)。
     */
    bool OnAddedToActiveContainer(FActiveGameplayEffectsContainer& ActiveGEContainer, FActiveGameplayEffect& ActiveGE) const;

    /**
     * 收到此游戏玩法效果已执行的通知(它必须是即时生效的,因为它不会添加到容器中)。
     * 由于它不会添加到容器中,因此不会有相关联的 FActiveGameplayEffect,只有 FGameplayEffectSpec。
     */
    void OnExecuted(FActiveGameplayEffectsContainer& ActiveGEContainer, FGameplayEffectSpec& GESpec, FPredictionKey& PredictionKey) const;

    /**
     * 收到此游戏玩法效果已应用的通知(此 GE 之前已添加到容器中或在这种情况下已执行)。
     * 然而,这也包括 GE 之前已添加到容器中,然后再次应用以 “堆叠” 的情况。对于有持续时间的 GE 的周期性执行不会发生这种情况。
     */
    void OnApplied(FActiveGameplayEffectsContainer& ActiveGEContainer, FGameplayEffectSpec& GESpec, FPredictionKey& PredictionKey) const;

    /** 返回此 GE “拥有” 且不会授予任何 Actor 的所有标签。 */
    const FGameplayTagContainer& GetAssetTags() const { return CachedAssetTags; }

    /** 返回此游戏玩法效果授予目标 Actor 的所有标签。也就是说:如果此 GE 应用于 Actor,他们将获得这些标签。 */
    const FGameplayTagContainer& GetGrantedTags() const { return CachedGrantedTags; }

    /** 返回此游戏玩法效果定义授予的所有阻塞技能标签。阻塞标签意味着目标将无法执行带有此资产标签的技能。 */
    const FGameplayTagContainer& GetBlockedAbilityTags() const { return CachedBlockedAbilityTags; }

    /** 返回此游戏玩法效果的最大堆叠大小 */
    int32 GetStackLimitCount() const;

    /** 返回此游戏玩法效果的堆叠过期策略 */
    EGameplayEffectStackingExpirationPolicy GetStackExpirationPolicy() const;
// ---------------------------------------------------------------------------------------------------------------------------------

// ---------------------------------------------------------------------------------------------------------------------------------
/**
 * 在这个游戏玩法效果(GE)中查找并返回指定类 `GEComponentClass` 的组件(如果存在)。
 * 注意:这里使用 `const` 是一种提示,表示这些是不应该在运行时修改的资产。如果你正在构建自己的动态游戏玩法效果,请参考 `AddComponent`、`FindOrAddComponent`。
 *
 * @return 匹配查询条件的组件(如果存在)。
 */
template<typename GEComponentClass>
const GEComponentClass* FindComponent() const;

/**
 * @return 如果存在,返回从传入的 `ClassToFind` 派生的第一个组件。
 */
const UGameplayEffectComponent* FindComponent(TSubclassOf<UGameplayEffectComponent> ClassToFind) const;

这两段代码定义了两个重载的 FindComponent 函数,用于在 UGameplayEffect 类中查找特定类型的组件。

模板函数 FindComponent

  • 功能:通过模板参数 GEComponentClass 指定要查找的组件类型,尝试在当前 UGameplayEffect 实例中找到该类型的组件。
  • 参数:无。
  • 返回值:如果找到匹配类型的组件,则返回指向该组件的常量指针;如果未找到,则返回 nullptr
  • 注意事项:使用 const 修饰函数,表示在函数内部不会修改对象的状态,暗示这些组件资产不应该在运行时被修改。如果需要动态添加或查找组件,可以使用 AddComponent 或 FindOrAddComponent 函数。

重载函数 FindComponent

    • 功能:通过传入一个 TSubclassOf<UGameplayEffectComponent> 类型的参数 ClassToFind,尝试在当前 UGameplayEffect 实例中找到从该类派生的第一个组件。
    • 参数:
      • ClassToFind:一个 TSubclassOf<UGameplayEffectComponent> 类型的参数,表示要查找的组件类的子类。
    • 返回值:如果找到匹配的组件,则返回指向该组件的常量指针;如果未找到,则返回 nullptr
/**
 * 向游戏玩法效果(GameplayEffect)中添加一个游戏玩法效果组件(GameplayEffectComponent)。此方法不会检查重复项,并且保证返回一个新实例。
 * 
 * @return 新添加的实例化游戏玩法效果组件。
 */
template<typename GEComponentClass>
GEComponentClass& AddComponent();

整体功能

这段代码定义了一个模板成员函数 AddComponent,其作用是向 UGameplayEffect 对象中添加一个指定类型的 GameplayEffectComponent 组件。该函数不会检查是否已经存在相同类型的组件,每次调用都会创建并返回一个新的组件实例。

详细解释

    • 模板参数:
      • GEComponentClass:这是一个模板类型参数,代表要添加的组件的具体类型。它必须是 UGameplayEffectComponent 类或其子类。
    • 返回值:
      • GEComponentClass&:返回一个对新添加的 GEComponentClass 类型组件的引用。通过返回引用,可以方便地对新添加的组件进行后续操作。
    • 功能特点:
      • 不检查重复项:函数不会去检查 UGameplayEffect 中是否已经存在相同类型的组件。这意味着多次调用该函数添加相同类型的组件时,会创建多个该类型的组件实例。
      • 保证返回新实例:每次调用该函数都会创建一个新的 GEComponentClass 类型的组件实例,并将其添加到 UGameplayEffect 中,然后返回对该新实例的引用。
/**
 * 查找请求类的现有游戏玩法效果组件(GameplayEffectComponent),如果未找到则添加一个。
 * 
 * @return GEComponentClass 的现有实例,或者是新添加的实例。
 */
template<typename GEComponentClass>
GEComponentClass& FindOrAddComponent();

此代码定义了一个模板成员函数 FindOrAddComponent,其目的是在 UGameplayEffect 对象中查找指定类型 GEComponentClass 的游戏玩法效果组件。若找到了该类型的现有组件,就返回对该组件的引用;若未找到,则创建一个新的该类型组件并添加到 UGameplayEffect 中,然后返回对新组件的引用。

详细解释

    1. 模板参数
      • GEComponentClass:模板类型参数,代表要查找或添加的组件类型。该类型必须是 UGameplayEffectComponent 类或其子类。
    2. 返回值
      • GEComponentClass&:返回一个对找到的或新添加的 GEComponentClass 类型组件的引用。这样做便于后续对该组件进行操作。
    3. 功能流程
      • 查找组件:函数会遍历 UGameplayEffect 中已有的组件列表,尝试找到类型为 GEComponentClass 的组件。
      • 添加组件:若在列表中未找到该类型的组件,函数会创建一个新的 GEComponentClass 类型组件,并将其添加到 UGameplayEffect 中。
      • 返回结果:无论是找到的现有组件还是新添加的组件,函数都会返回对该组件的引用。
#if WITH_EDITOR
    /**
     * 允许每个游戏玩法效果组件验证其自身的数据。
     * 在你重写的版本之后调用此版本(Super::IsDataValid),以更新编辑器状态文本。
     */
    virtual EDataValidationResult IsDataValid(class FDataValidationContext& Context) const override;

整体功能

 

这段代码定义了一个虚函数 IsDataValid,它主要用于在编辑器环境下(由 #if WITH_EDITOR 条件判断可知)对游戏玩法效果组件的数据进行验证。每个游戏玩法效果组件可以重写这个函数来实现自己的数据验证逻辑,同时在重写的函数中调用基类版本(Super::IsDataValid)来更新编辑器中的状态文本。

详细解释

    1. 条件编译指令 #if WITH_EDITOR
      • 这是一个条件编译指令,WITH_EDITOR 通常是 Unreal Engine 中的一个宏,用于区分是否处于编辑器环境。只有在编辑器环境下,这段代码才会被编译,确保该功能仅在开发阶段可用。
    2. 函数声明
      • 函数名:IsDataValid
      • 返回值:EDataValidationResult,这是一个枚举类型,用于表示数据验证的结果,可能的值有验证成功、验证失败等。
      • 参数:class FDataValidationContext& ContextFDataValidationContext 是一个上下文类,可能包含了验证所需的各种信息,如验证的对象、相关的配置等。
      • 修饰符:
        • virtual:表示这是一个虚函数,允许派生类重写该函数以实现自己的验证逻辑。
        • const:表示该函数不会修改调用对象的状态。
        • override:明确表示这是对基类中同名虚函数的重写,有助于编译器进行检查,确保重写的正确性。
    3. 函数用途
      • 派生类可以重写这个函数,实现自己特定的数据验证逻辑。例如,某个游戏玩法效果组件可能需要验证其配置的技能冷却时间是否为正数等。
      • 在重写的函数中,通常需要调用基类的 IsDataValid 函数(即 Super::IsDataValid),以确保编辑器状态文本得到更新,方便开发者在编辑器中查看验证结果。
protected:
    // ----------------------------------------------------------------------
    //  升级路径
    // ----------------------------------------------------------------------
    
    /**
     * 我们需要跟踪版本,以便正确地升级组件。升级后,这个版本号会在 PostLoad 阶段被正确设置。
     */
    EGameplayEffectVersion GetVersion() const;

    /**
     * 设置类的版本,以表明它已经过升级。
     */
    void SetVersion(EGameplayEffectVersion Version);

    /**
     * 我们应该拦截保存调用,并重新验证所有已弃用的值,以避免保留过时的数据。
     */
    virtual void PreSave(FObjectPreSaveContext SaveContext) override;

整体功能

 

这部分代码定义了与游戏玩法效果(UGameplayEffect)版本管理和数据保存前处理相关的功能,主要目的是确保在游戏开发过程中,组件能够正确升级,并且在保存数据时避免保留过时或弃用的数据。

详细解释

 

    1. 版本跟踪相关函数
      • EGameplayEffectVersion GetVersion() const;
        • 功能:获取当前 UGameplayEffect 的版本号。通过跟踪版本号,可以知道该对象处于哪个版本状态,从而在升级时采取相应的操作。
        • 返回值:EGameplayEffectVersion 类型的版本号,这是一个自定义的枚举类型,用于表示不同的版本。
        • 修饰符:const 表示该函数不会修改对象的状态。
      • void SetVersion(EGameplayEffectVersion Version);
        • 功能:设置当前 UGameplayEffect 的版本号。通常在完成升级操作后调用此函数,以标记对象已经升级到新的版本。
        • 参数:Version 是 EGameplayEffectVersion 类型的版本号,用于指定要设置的版本。
    2. 保存前处理函数
      • virtual void PreSave(FObjectPreSaveContext SaveContext) override;
        • 功能:在对象保存之前被调用,用于拦截保存操作并进行一些预处理。具体来说,它会重新验证所有已弃用的值,确保不会将过时的数据保存到文件中。
        • 参数:FObjectPreSaveContext 类型的 SaveContext,它包含了保存操作的上下文信息,例如保存的目标位置、保存的方式等。
        • 修饰符:
          • virtual:表示这是一个虚函数,允许派生类重写该函数以实现自定义的保存前处理逻辑。
          • override:明确表示这是对基类中同名虚函数的重写,有助于编译器进行检查,确保重写的正确性。
  • 版本管理:在游戏开发过程中,游戏玩法效果的实现可能会随着时间推移而发生变化。通过版本管理,可以在加载旧版本的对象时进行升级操作,确保它们能够正常工作。例如,在后续版本中可能会添加新的组件或修改现有组件的行为,通过版本号可以判断是否需要对旧对象进行升级。
  • 数据清理:随着游戏的更新,一些旧的属性或配置可能会被弃用。在保存对象时,通过 PreSave 函数重新验证这些弃用的值,可以避免将过时的数据保存下来,从而减少数据文件的大小并提高数据的一致性。
// 获取版本号
EGameplayEffectVersion currentVersion = GetVersion();

// 进行升级操作
// ...

// 设置新的版本号
SetVersion(NewVersion);

// 重写 PreSave 函数
void MyGameplayEffect::PreSave(FObjectPreSaveContext SaveContext)
{
    // 重新验证弃用的值
    // ...

    // 调用基类的 PreSave 函数
    Super::PreSave(SaveContext);
}

在上述示例中,首先获取当前版本号,进行升级操作后设置新的版本号。然后在派生类中重写 PreSave 函数,实现自定义的弃用值验证逻辑,并调用基类的 PreSave 函数以确保保存操作的正常进行。
AI用例

这部分代码定义了一系列私有成员函数,这些函数作为辅助工具,用于将现有的数据转换为使用组件的形式。在游戏开发中,可能会随着项目的演进,将原本分散的数据整合到组件系统中,这些函数就是为了完成这种数据转换而设计的。

private:
    // 用于将数据转换为使用组件的辅助函数
    void ConvertAbilitiesComponent(); // 转换技能组件数据
    void ConvertAdditionalEffectsComponent(); // 转换附加效果组件数据
    void ConvertAssetTagsComponent(); // 转换资产标签组件数据
    void ConvertBlockByTagsComponent(); // 转换按标签阻塞组件数据
    void ConvertChanceToApplyComponent(); // 转换应用概率组件数据
    void ConvertCustomCanApplyComponent(); // 转换自定义应用条件组件数据
    void ConvertImmunityComponent(); // 转换免疫组件数据
    void ConvertRemoveOtherComponent(); // 转换移除其他效果组件数据
    void ConvertTagRequirementsComponent(); // 转换标签要求组件数据
    void ConvertTargetTagsComponent(); // 转换目标标签组件数据
    void ConvertUIComponent(); // 转换用户界面组件数据
#endif (#if WITH_EDITOR)

开始正式部分而不是上面的EDITOR部分

 

内部变量

// ----------------------------------------------------------------------
//  属性
// ----------------------------------------------------------------------
public:
    /** 此效果的持续时间策略 */
    UPROPERTY(EditDefaultsOnly, Category=Duration)
    EGameplayEffectDurationType DurationPolicy;

    /** 效果持续时间(秒)。0.0 表示即时生效的效果;-1.0 表示持续时间无限。 */
    UPROPERTY(EditDefaultsOnly, Category=Duration, meta=(EditCondition="DurationPolicy == EGameplayEffectDurationType::HasDuration", EditConditionHides))
    FGameplayEffectModifierMagnitude DurationMagnitude;

    /** 效果触发的周期(秒)。0.0 表示非周期性效果 */
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Duration|Period", meta=(EditCondition="DurationPolicy != EGameplayEffectDurationType::Instant", EditConditionHides))
    FScalableFloat Period;
//*************************是否先执行再计时***************
    /** 如果为 true,效果在应用时立即执行,然后按周期间隔执行;如果为 false,直到第一个周期结束才开始执行。 */
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Duration|Period", meta=(EditCondition="true", EditConditionHides)) // EditCondition 在 FGameplayEffectDetails 中定义
    bool bExecutePeriodicEffectOnApplication;

    /** 当周期性游戏玩法效果不再受抑制时的响应策略 */
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Duration|Period", meta=(EditCondition="true", EditConditionHides)) // EditCondition 在 FGameplayEffectDetails 中定义
    EGameplayEffectPeriodInhibitionRemovedPolicy PeriodicInhibitionPolicy;

    /** 会影响此效果目标的修饰符数组 */
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category=GameplayEffect, meta=(TitleProperty=Attribute))
    TArray<FGameplayModifierInfo> Modifiers;

    /** 会影响此效果目标的执行操作数组 */
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = GameplayEffect)
    TArray<FGameplayEffectExecutionDefinition> Executions;
//*************************应用概率***************
    /** 此GE应用到目标角色的概率(0.0 表示从不应用,1.0 表示总是应用) */
    UE_DEPRECATED(5.3, "应用到目标的概率已弃用。请使用 UChanceToApplyGameplayEffectComponent 代替。")
    UPROPERTY(meta = (GameplayAttribute = "True", DeprecatedProperty))
    FScalableFloat ChanceToApplyToTarget_DEPRECATED;
//*************************应用所需要的条件***************
    UE_DEPRECATED(5.3, "应用要求已弃用。请使用 UCustomCanApplyGameplayEffectComponent 代替。")
    UPROPERTY(meta = (DisplayName = "应用要求", DeprecatedProperty))
    TArray<TSubclassOf<UGameplayEffectCustomApplicationRequirement> > ApplicationRequirements_DEPRECATED;

//*************************别的效果一旦起效就应用这个***************
/** 如果此效果成功应用,将对目标应用的其他游戏玩法效果 */ UE_DEPRECATED(5.3, "条件游戏玩法效果已弃用。请使用 UAdditionalEffectsGameplayEffectComponent 代替。") UPROPERTY(BlueprintReadOnly, Category = "Deprecated|GameplayEffect", meta = (DeprecatedProperty)) TArray<FConditionalGameplayEffect> ConditionalGameplayEffects;
//*********************************堆叠满了还会继续堆叠***************
/** 当堆叠效果尝试再次堆叠而导致堆叠数量溢出时要应用的效果。无论溢出应用是否成功都会添加。 */ UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Stacking|Overflow", meta = (EditConditionHides, EditCondition = "StackingType != EGameplayEffectStackingType::None")) TArray<TSubclassOf<UGameplayEffect>> OverflowEffects;
//*********************************堆叠满时不会再堆叠***************
/** 如果为 true,当达到堆叠上限时,后续的堆叠尝试将失败,效果的持续时间和上下文不会刷新 */ UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Stacking|Overflow", meta = (EditConditionHides, EditCondition = "StackingType != EGameplayEffectStackingType::None")) bool bDenyOverflowApplication;
//*********************************堆叠满时清除***************
/** 如果为 true,效果堆叠溢出时,整个效果堆叠将被清除 */
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Stacking|Overflow", meta=(EditConditionHides, EditCondition="(StackingType != EGameplayEffectStackingType::None) && bDenyOverflowApplication"))
    bool bClearStackOnOverflow;
//*********************************提前取消时触发CUE***************
/** 当此效果提前过期(例如通过强制移除、清除标签等方式)时要应用的效果;仅适用于有持续时间的效果 */
    UE_DEPRECATED(5.3, "提前过期效果类已弃用。请使用 UAdditionalEffectsGameplayEffectComponent 代替。")
    UPROPERTY(BlueprintReadOnly, Category="Deprecated|Expiration", meta = (DeprecatedProperty))
    TArray<TSubclassOf<UGameplayEffect>> PrematureExpirationEffectClasses;
//*********************************过期时触发CUE***************
/** 当此效果因持续时间结束而自然过期时要应用的效果;仅适用于有持续时间的效果 */
    UE_DEPRECATED(5.3, "常规过期效果类已弃用。请使用 UAdditionalEffectsGameplayEffectComponent 代替。")
    UPROPERTY(BlueprintReadOnly, Category="Deprecated|Expiration", meta = (DeprecatedProperty))
    TArray<TSubclassOf<UGameplayEffect>> RoutineExpirationEffectClasses;
//*********************************仅成功时触发CUE***************
/** 如果为 true,游戏玩法提示(Gameplay Cues)仅在游戏玩法效果(GE)的修饰符成功应用(无论是通过修饰符还是执行操作)时触发 */ UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "GameplayCues") bool bRequireModifierSuccessToTriggerCues; 
//*********************************单次触发CUE***************
/** 如果为 true,游戏玩法提示仅在堆叠GE的第一个实例触发 */ UPROPERTY(EditDefaultsOnly, Category = "GameplayCues") bool bSuppressStackingCues;
//*********************************触发CUE***************
/** 为响应此游戏玩法效果而触发的非模拟反应提示,如声音、粒子效果等 */
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "GameplayCues")
    TArray<FGameplayEffectCue> GameplayCues;

//**********************************UI***********************
/** 此效果的用户界面展示数据。应包含文本、图标等信息。仅服务器版本中不可用。 */ UE_DEPRECATED(5.3, "UI 数据已弃用。UGameplayEffectUIData 现在继承自 UGameplayEffectComponent,请将其作为游戏玩法效果组件添加。你可以使用 FindComponent<UGameplayEffectUIData>() 访问它。") UPROPERTY(BlueprintReadOnly, Transient, Instanced, Category = "Deprecated|Display", meta = (DeprecatedProperty)) TObjectPtr<class UGameplayEffectUIData> UIData;

 

内部TAGS

// ----------------------------------------------------------------------
//  标签容器
// ----------------------------------------------------------------------

//**********************************仅GE持有*********************** /** 游戏玩法效果自身的标签:这些标签是游戏玩法效果(GE)所拥有的,但不会赋予给应用该效果的角色。 */ UE_DEPRECATED(5.3, "可继承的游戏玩法效果标签已弃用。若要配置,请添加 UAssetTagsGameplayEffectComponent;若要访问,请使用 GetAssetTags。") UPROPERTY(BlueprintReadOnly, Category = Deprecated, meta = (DisplayName = "GameplayEffectAssetTag", Categories="GameplayEffectTagsCategory", DeprecatedProperty)) FInheritedTagContainer InheritableGameplayEffectTags;
//**********************************会挂到目标上***********************
/** 这些标签会被应用到我所作用的角色上 */ UE_DEPRECATED(5.3, "可继承的拥有标签容器已弃用。若要配置,请添加 UTargetTagsGameplayEffectComponent;若要访问,请使用 GetGrantedTags。") UPROPERTY(BlueprintReadOnly, Category = Deprecated, meta = (DisplayName="GrantedTags", Categories="OwnedTagsCategory", DeprecatedProperty)) FInheritedTagContainer InheritableOwnedTagsContainer;
//**********************************会挂到目标上的阻塞标签***********************
/** 这些阻塞技能的标签会被应用到我所作用的角色上 */ UE_DEPRECATED(5.3, "可继承的阻塞技能标签容器已弃用。请使用 UTargetTagsGameplayEffectComponent 代替;若要访问,请使用 GetBlockedAbilityTags。") UPROPERTY(BlueprintReadOnly, Category = Deprecated, meta = (DisplayName="GrantedBlockedAbilityTags", Categories="BlockedAbilityTagsCategory", DeprecatedProperty)) FInheritedTagContainer InheritableBlockedAbilityTagsContainer;
//**********************************挂着但是可以开关***********************
/** 一旦应用,这些标签要求用于确定游戏玩法效果是 “开启” 还是 “关闭”。游戏玩法效果可以处于关闭状态而不产生任何效果,但仍然处于应用状态。 */ UE_DEPRECATED(5.3, "持续标签要求已弃用。请使用 UTargetTagRequirementsGameplayEffectComponent 代替。") UPROPERTY(BlueprintReadOnly, Category = Deprecated, meta = (Categories="OngoingTagRequirementsCategory", DeprecatedProperty)) FGameplayTagRequirements OngoingTagRequirements;
//**********************************应用时进行判断***********************
/** 此游戏玩法效果应用到目标的标签要求。在应用时进行判断,通过则应用成功,失败则应用失败。 */ UE_DEPRECATED(5.3, "应用标签要求已弃用。请使用 UTargetTagRequirementsGameplayEffectComponent 代替。") UPROPERTY(BlueprintReadOnly, Category = Deprecated, meta = (Categories="ApplicationTagRequirementsCategory", DeprecatedProperty)) FGameplayTagRequirements ApplicationTagRequirements;
//**********************************阻止标签***********************
/** 如果满足这些标签要求,将移除该效果。同时也会阻止效果的应用。 */ UE_DEPRECATED(5.3, "移除标签要求已弃用。请使用 URemoveOtherGameplayEffectComponent 代替。") UPROPERTY(BlueprintReadOnly, Category = Deprecated, meta = (Categories="ApplicationTagRequirementsCategory", DeprecatedProperty)) FGameplayTagRequirements RemovalTagRequirements;
//**********************************移除标签***********************
/** 应用此效果时,任何拥有此容器中标签的游戏玩法效果都将被清除。 */ UE_DEPRECATED(5.3, "移除带有特定标签的游戏玩法效果已弃用。请使用 UTargetTagRequirementsGameplayEffectComponent 代替。") UPROPERTY(BlueprintReadOnly, Category = Deprecated, meta = (Categories="RemoveTagRequirementsCategory", DeprecatedProperty)) FInheritedTagContainer RemoveGameplayEffectsWithTags;
//**********************************拥有此GE者免疫标签***********************
/** 赋予拥有者对这些来源标签的免疫能力。 */ UE_DEPRECATED(5.3, "授予的应用免疫标签已弃用。请使用 UImmunityGameplayEffectComponent 代替。") UPROPERTY(BlueprintReadOnly, Category = Deprecated, meta = (DisplayName = "GrantedApplicationImmunityTags", Categories="GrantedApplicationImmunityTagsCategory", DeprecatedProperty)) FGameplayTagRequirements GrantedApplicationImmunityTags;
//**********************************查询GE免疫TAG***********************
/** 赋予对符合此查询条件的游戏玩法效果的免疫能力。查询功能更强大,但比授予的应用免疫标签稍慢。 */ UE_DEPRECATED(5.3, "授予的应用免疫查询已弃用。请使用 UImmunityGameplayEffectComponent 代替。") UPROPERTY(BlueprintReadOnly, Category = Deprecated, meta = (DeprecatedProperty)) FGameplayEffectQuery GrantedApplicationImmunityQuery;
//**********************************查询是否有免疫TAG***********************
/** 缓存的 !GrantedApplicationImmunityQuery.IsEmpty() 的结果。在 PostLoad 阶段设置。 */ UE_DEPRECATED(5.3, "是否有授予的应用免疫查询已弃用。请使用 UImmunityGameplayEffectComponent 代替。") bool HasGrantedApplicationImmunityQuery = false;
//**********************************移除GE查询***********************
/** 应用效果时,任何与添加效果匹配此查询条件的活动效果都将被移除。查询功能更强大,但比移除带有特定标签的游戏玩法效果稍慢。 */ UE_DEPRECATED(5.3, "移除游戏玩法效果查询已弃用。请使用 URemoveOtherGameplayEffectComponent 代替。") UPROPERTY(BlueprintReadOnly, Category = Tags, meta = (DisplayAfter = "RemovalTagRequirements", DeprecatedProperty)) FGameplayEffectQuery RemoveGameplayEffectQuery;
//**********************************是否有移除GE查询***********************
/** 缓存的 !RemoveGameplayEffectsQuery.IsEmpty() 的结果。在 PostLoad 阶段设置。 */ UE_DEPRECATED(5.3, "是否有移除GE查询已弃用。请使用 URemoveOtherGameplayEffectComponent 代替。") bool HasRemoveGameplayEffectsQuery = false;
详细解释
标签容器属性
InheritableGameplayEffectTags:存储游戏玩法效果自身的标签,这些标签不会传递给应用该效果的角色。现在建议使用 UAssetTagsGameplayEffectComponent 进行配置,并通过 GetAssetTags 方法访问。
InheritableOwnedTagsContainer:存储要赋予应用该效果的角色的标签。现在建议使用 UTargetTagsGameplayEffectComponent 进行配置,并通过 GetGrantedTags 方法访问。
InheritableBlockedAbilityTagsContainer:存储要应用到目标角色上,用于阻塞某些技能的标签。建议使用 UTargetTagsGameplayEffectComponent 替代,通过 GetBlockedAbilityTags 访问。
标签要求属性
OngoingTagRequirements:用于确定游戏玩法效果是处于 “开启” 还是 “关闭” 状态的标签要求。现在建议使用 UTargetTagRequirementsGameplayEffectComponent 代替。
ApplicationTagRequirements:游戏玩法效果应用到目标的标签要求,若不满足则无法应用。建议使用 UTargetTagRequirementsGameplayEffectComponent 替代。
RemovalTagRequirements:满足这些标签要求时,会移除该效果,同时也会阻止效果的应用。建议使用 URemoveOtherGameplayEffectComponent 代替。
效果移除相关属性
RemoveGameplayEffectsWithTags:应用此效果时,会清除所有拥有此容器中标签的其他游戏玩法效果。建议使用 UTargetTagRequirementsGameplayEffectComponent 替代。
RemoveGameplayEffectQuery:应用效果时,会移除所有与添加效果匹配此查询条件的活动效果。建议使用 URemoveOtherGameplayEffectComponent 代替。
免疫相关属性
GrantedApplicationImmunityTags:赋予拥有者对特定来源标签的免疫能力。建议使用 UImmunityGameplayEffectComponent 替代。
GrantedApplicationImmunityQuery:赋予对符合特定查询条件的游戏玩法效果的免疫能力。建议使用 UImmunityGameplayEffectComponent 代替。
HasGrantedApplicationImmunityQuery 和 HasRemoveGameplayEffectsQuery:分别是对 GrantedApplicationImmunityQuery 和 RemoveGameplayEffectQuery 是否为空的缓存结果,均已弃用,推荐使用新组件。
这些属性都使用了 UE_DEPRECATED 宏进行标记,提示开发者这些功能已经过时,应该使用新的组件来实现相同或更强大的功能,避免在后续开发中使用这些旧的属性导致兼容性和可维护性问题。
详细解释

堆叠处理

// ----------------------------------------------------------------------
//  堆叠机制
// ----------------------------------------------------------------------

/** 此游戏玩法效果与该游戏玩法效果的其他实例如何进行堆叠 */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Stacking)
EGameplayEffectStackingType    StackingType;

/** 堆叠类型的堆叠上限 */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Stacking, meta = (EditConditionHides, EditCondition = "StackingType != EGameplayEffectStackingType::None"))
int32 StackLimitCount;

/** 堆叠时效果持续时间的刷新策略 */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Stacking, meta = (EditConditionHides, EditCondition = "StackingType != EGameplayEffectStackingType::None"))
EGameplayEffectStackingDurationPolicy StackDurationRefreshPolicy;

/** 堆叠时效果触发周期的重置策略(是否重置) */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Stacking, meta = (EditConditionHides, EditCondition = "StackingType != EGameplayEffectStackingType::None"))
EGameplayEffectStackingPeriodPolicy StackPeriodResetPolicy;

/** 处理此游戏玩法效果持续时间到期的策略 */
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Stacking, meta = (EditConditionHides, EditCondition = "StackingType != EGameplayEffectStackingType::None"))
EGameplayEffectStackingExpirationPolicy StackExpirationPolicy;

详细解释

  1. StackingType 属性
    • 类型:EGameplayEffectStackingType 枚举类型。
    • 用途:定义了当前游戏玩法效果与自身其他实例的堆叠方式。例如,可能有不堆叠、简单堆叠、覆盖堆叠等不同的方式。
    • 配置说明:EditDefaultsOnly 表示该属性只能在默认值编辑器中编辑,BlueprintReadOnly 表示在蓝图中该属性只读,Category = Stacking 表明该属性属于 “Stacking” 类别。
  2. StackLimitCount 属性
    • 类型:int32
    • 用途:指定当前堆叠类型下的堆叠上限。即该游戏玩法效果最多可以在目标上堆叠的次数。
    • 配置说明:只有当 StackingType 不为 EGameplayEffectStackingType::None(即存在堆叠机制)时,该属性才可见并可编辑。这是通过 meta 元数据中的 EditCondition 实现的。
  3. StackDurationRefreshPolicy 属性
    • 类型:EGameplayEffectStackingDurationPolicy 枚举类型。
    • 用途:定义了在堆叠过程中效果持续时间的刷新策略。比如每次堆叠时持续时间重置、不重置、按一定规则延长等。
    • 配置说明:同样,只有当 StackingType 不为 EGameplayEffectStackingType::None 时,该属性才可见并可编辑。
  4. StackPeriodResetPolicy 属性
    • 类型:EGameplayEffectStackingPeriodPolicy 枚举类型。
    • 用途:确定在堆叠时效果触发周期的重置策略。例如,每次堆叠时周期是否重置、保持不变等。
    • 配置说明:条件与上述类似,仅在存在堆叠机制时可配置。
  5. StackExpirationPolicy 属性
    • 类型:EGameplayEffectStackingExpirationPolicy 枚举类型。
    • 用途:规定了该游戏玩法效果持续时间到期时的处理策略。比如到期后移除所有堆叠、移除一层堆叠等。
    • 配置说明:也是只有在存在堆叠机制时才可以对其进行配置。
通过这些属性的配置,可以灵活地控制游戏玩法效果的堆叠行为,以满足不同游戏设计的需求。
 
// ----------------------------------------------------------------------
//  授予的技能
// ----------------------------------------------------------------------

/** 此游戏玩法效果(GE)授予技能的策略。 */
UE_DEPRECATED(5.3, "授予的技能已弃用,推荐使用 AbilitiesGameplayEffectComponent 替代")
UPROPERTY(BlueprintReadOnly, Category = "Granted Abilities")
TArray<FGameplayAbilitySpecDef>    GrantedAbilities;

整体功能

这段代码定义了一个与游戏玩法效果(GameplayEffect)相关的属性,用于管理该效果所能授予的技能。不过,这个功能已经被弃用,推荐使用新的 AbilitiesGameplayEffectComponent 组件来实现相同的功能。

详细解释

    1. 属性用途
      • GrantedAbilities 是一个 TArray<FGameplayAbilitySpecDef> 类型的数组。FGameplayAbilitySpecDef 通常是用于定义游戏玩法技能(GameplayAbility)规格的结构体,包含了技能的各种属性,如技能的等级、激活条件、冷却时间等。
      • 该数组存储了此游戏玩法效果可以授予目标的技能列表。当这个游戏玩法效果应用到某个目标上时,目标可能会获得这些技能。
    2. 属性修饰符
      • UE_DEPRECATED(5.3, "GrantedAbilities are deprecated in favor of AbilitiesGameplayEffectComponent"):这是 Unreal Engine 提供的宏,用于标记该属性已被弃用。从引擎版本 5.3 开始,不建议再使用这个属性,而是推荐使用 AbilitiesGameplayEffectComponent 组件来处理授予技能的逻辑。
      • UPROPERTY(BlueprintReadOnly, Category = "Granted Abilities")
        • BlueprintReadOnly 表示该属性在蓝图中是只读的,即只能在蓝图中查看该属性的值,不能对其进行修改。
        • Category = "Granted Abilities" 为该属性指定了一个类别,在 Unreal Engine 的编辑器中,属性会按照类别进行分组显示,方便开发者管理和查找。
// ----------------------------------------------------------------------
//  缓存的组件数据 - 请勿在运行时修改这些数据!
//  如果你想操作这些数据,请编写自己的 GameplayEffectComponent,并在 PostLoad 阶段设置数据。
// ----------------------------------------------------------------------

/** 此游戏玩法效果(GE)拥有的所有标签的缓存副本。数据在 PostLoad 阶段填充。 */
FGameplayTagContainer CachedAssetTags;

/** 此游戏玩法效果授予其目标的所有标签的缓存副本。数据在 PostLoad 阶段填充。 */
FGameplayTagContainer CachedGrantedTags;

/** 此游戏玩法效果应用到其目标以阻塞游戏玩法技能的所有标签的缓存副本。数据在 PostLoad 阶段填充。 */
FGameplayTagContainer CachedBlockedAbilityTags;
缓存的组件数据 - 请勿在运行时修改这些数据!

 

protected:
    /** 这些GEC定义了此GE在应用时的行为 */
    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Instanced, Category = "GameplayEffect", meta = (DisplayName = "Components", TitleProperty = EditorFriendlyName, ShowOnlyInnerProperties, DisplayPriority = 0))
    TArray<TObjectPtr<UGameplayEffectComponent>> GEComponents;

详细解释

 

    1. GEComponents 属性
      • 类型:TArray<TObjectPtr<UGameplayEffectComponent>>,这是一个存储 UGameplayEffectComponent 指针的数组。TObjectPtr 是 Unreal Engine 中用于管理对象指针的智能指针类型,UGameplayEffectComponent 应该是自定义的组件类,用于定义游戏玩法效果的具体行为。
      • 访问修饰符:protected,意味着该属性只能在类内部或派生类中访问。
      • UPROPERTY 元数据:
        • EditDefaultsOnly:表示该属性只能在默认值编辑器中编辑,在运行时不可修改。
        • BlueprintReadOnly:在蓝图中该属性只读,不能修改。
        • Instanced:表示这些组件是实例化的对象,需要在编辑器中进行创建和配置。
        • Category = "GameplayEffect":将该属性归类到 “GameplayEffect” 类别中,方便在编辑器中查找和管理。
        • meta 元数据:
          • DisplayName = "Components":在编辑器中显示的名称为 “Components”。
          • TitleProperty = EditorFriendlyName:使用组件的 EditorFriendlyName 属性作为显示标题。
          • ShowOnlyInnerProperties:只显示组件的内部属性。
          • DisplayPriority = 0:显示优先级为 0。
#if WITH_EDITORONLY_DATA
    /** 允许我们在编辑器中配置时显示类的状态(有效配置或无效配置) */
    UPROPERTY(VisibleAnywhere, Transient, Category = Status)
    mutable FText EditorStatusText;

private:
    /** 此包的保存版本(该值不会从其父类继承)。请参阅 SetVersion 和 GetVersion。 */
    UPROPERTY()
    FGameplayEffectVersion DataVersion;
#endif
EDITOR信息
  1. EditorStatusText 属性(仅在编辑器环境)
    • 条件编译:#if WITH_EDITORONLY_DATA 确保该属性只在编辑器环境下编译。
    • 类型:FText,用于存储可本地化的文本信息。
    • 访问修饰符:mutable 表示即使在 const 成员函数中也可以修改该属性。
    • UPROPERTY 元数据:
      • VisibleAnywhere:该属性在任何地方都可见。
      • Transient:表示该属性不会被保存到磁盘,只在运行时存在。
      • Category = Status:归类到 “Status” 类别,用于显示类的状态信息,如配置是否有效等。
  2. DataVersion 属性(仅在编辑器环境)
    • 条件编译:同样受 #if WITH_EDITORONLY_DATA 限制,只在编辑器环境下存在。
    • 类型:FGameplayEffectVersion,应该是自定义的版本号类型,用于记录游戏玩法效果数据的版本。
    • 访问修饰符:private,只能在类内部访问。
    • UPROPERTY 元数据:没有额外的元数据说明,使用默认的保存和访问规则。该版本号不会从父类继承,通过 SetVersion 和 GetVersion 方法进行管理。

 

posted @ 2025-02-19 01:41  mcwhirr  阅读(102)  评论(0)    收藏  举报