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

// Copyright Epic Games, Inc. All Rights Reserved.
// 版权所有 (c) Epic Games, Inc. 保留所有权利。

#pragma once

#include "CoreMinimal.h"
#include "UObject/ObjectMacros.h"
#include "GameplayEffectCalculation.h"
#include "GameplayEffect.h"
#include "GameplayModMagnitudeCalculation.generated.h"

/** 
 * 用于通过蓝图或原生代码执行自定义游戏玩法效果修饰符计算的类 
 */
UCLASS(BlueprintType, Blueprintable, Abstract)
class GAMEPLAYABILITIES_API UGameplayModMagnitudeCalculation : public UGameplayEffectCalculation
{
public:
    GENERATED_UCLASS_BODY()

    /**
     * 根据指定的规格计算游戏玩法效果修饰符的基础幅度。请注意,拥有该规格定义的对象仍可以使用系数以及预乘和后乘加法来修改此基础值。
     * 详细信息请参阅 FCustomCalculationBasedFloat::CalculateMagnitude。
     * 
     * @param Spec 用于计算幅度的游戏玩法效果规格
     * 
     * @return 计算得到的修饰符幅度
     */
    UFUNCTION(BlueprintNativeEvent, Category="Calculation")
    float CalculateBaseMagnitude(const FGameplayEffectSpec& Spec) const;

    /**
     * 如果自定义计算得出的幅度依赖于游戏代码特定的条件,而这些条件不在技能系统的管辖范围内,
     * 则应重写此方法,以提供一个多播委托,该委托将在依赖条件发生变化时触发,以便重新计算和更新幅度。
     * 
     * @param Spec 请求委托的游戏玩法效果规格
     * @param World 请求委托的 UWorld 对象
     * 
     * @return 如果有外部依赖项发生变化时将触发的多播委托,否则返回 nullptr
     */
    virtual FOnExternalGameplayModifierDependencyChange* GetExternalModifierDependencyMulticast(const FGameplayEffectSpec& Spec, UWorld* World) const;

    /** 
     * 一个简单的访问器,用于访问 bAllowNonNetAuthorityDependencyRegistration 变量,并进行一些验证。
     * 请阅读该变量的注释以了解其使用方法!!!
     */
    bool ShouldAllowNonNetAuthorityDependencyRegistration() const;

protected:
    /** 
     * 在 CalculateMagnitude 调用期间获取属性幅度的便捷方法 
     * 
     * @param Def 游戏玩法效果属性捕获定义
     * @param Spec 游戏玩法效果规格
     * @param EvaluationParameters 聚合评估参数
     * @param Magnitude [out] 输出的属性幅度值
     * 
     * @return 如果成功获取到属性幅度,则返回 true,否则返回 false
     */
    bool GetCapturedAttributeMagnitude(const FGameplayEffectAttributeCaptureDefinition& Def, const FGameplayEffectSpec& Spec, const FAggregatorEvaluateParameters& EvaluationParameters, OUT float& Magnitude) const;

    /** 
     * 该计算是否允许非网络权威方注册外部依赖多播委托;实际上就是是否允许客户端自行执行自定义计算。
     * 
     * @注意:这是一个高级用例,仅应在非常特定的情况下启用。此功能是为那些使用网络休眠机制的游戏设计的,
     * 这些游戏可能希望信任客户端在不导致网络休眠刷新的情况下在客户端更新非游戏玩法关键属性。使用此标志与计算中的属性捕获不兼容,
     * 如果同时使用会触发断言。客户端无法执行需要属性捕获的自定义计算。一般来说,如果你的游戏不使用网络休眠,
     * 则应始终禁用此功能。
     *
     * @注意:如果为自定义计算启用此功能,请确保外部委托的来源是保证在客户端上存在的,以避免出现计时问题。
     * 例如,绑定到 GameState 上的委托可能不可靠,因为客户端在注册时可能无法获取到该 Actor 的引用。
     */
    UPROPERTY(EditDefaultsOnly, Category=ExternalDependencies, AdvancedDisplay)
    bool bAllowNonNetAuthorityDependencyRegistration;

    /**
     * 获取给定属性的捕获幅度值。
     * 为了使此方法正常工作,需要将该属性添加到要捕获的相关属性数组中。
     *
     * @param EffectSpec 从中获取信息的游戏玩法效果规格
     * @param Attribute 要查询的属性
     *
     * @return 如果找到幅度值,则返回该值;否则返回零
     */
    UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Ability|GameplayEffect", meta=(DisplayName="Get Captured Attribute Magnitude", ScriptName="GetCapturedAttributeMagnitude"))
    float K2_GetCapturedAttributeMagnitude(const FGameplayEffectSpec& EffectSpec, FGameplayAttribute Attribute, const FGameplayTagContainer& SourceTags, const FGameplayTagContainer& TargetTags) const;

    /**
     * 从游戏玩法效果规格中提取由调用者设置的幅度值。
     *
     * @param EffectSpec 从中获取信息的游戏玩法效果规格
     * @param Tag 要查询的效果标签
     * 
     * @return 如果找到幅度值,则返回该值;否则返回零
     */
    UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Ability|GameplayEffect")
    float GetSetByCallerMagnitudeByTag(const FGameplayEffectSpec& EffectSpec, const FGameplayTag& Tag) const;

    /**
     * 从游戏玩法效果规格中提取由调用者设置的幅度值。
     *
     * @param EffectSpec 从中获取信息的游戏玩法效果规格
     * @param MagnitudeName 要查询的效果名称
     * 
     * @return 如果找到幅度值,则返回该值;否则返回零
     */
    UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Ability|GameplayEffect")
    float GetSetByCallerMagnitudeByName(const FGameplayEffectSpec& EffectSpec, const FName& MagnitudeName) const;

    /**
     * 从游戏玩法效果规格中复制并返回源聚合标签。
     *
     * @param EffectSpec 从中获取信息的游戏玩法效果规格
     * 
     * @return 包含复制标签的游戏玩法标签容器。如果不存在捕获的源标签,则容器为空。
     */
    UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Ability|GameplayEffect")
    FGameplayTagContainer GetSourceAggregatedTags(const FGameplayEffectSpec& EffectSpec) const;

    /**
     * 从游戏玩法效果规格中返回源 Actor 标签。
     *
     * @param EffectSpec 从中获取信息的游戏玩法效果规格
     * 
     * @return 包含复制标签的游戏玩法标签容器。如果不存在捕获的源标签,则容器为空。
     */
    UFUNCTION(BlueprintCallable, Category = "Ability|GameplayEffect")
    const FGameplayTagContainer& GetSourceActorTags(const FGameplayEffectSpec& EffectSpec) const;

    /**
     * 从游戏玩法效果规格中返回源规格标签。
     *
     * @param EffectSpec 从中获取信息的游戏玩法效果规格
     * 
     * @return 包含复制标签的游戏玩法标签容器。如果不存在捕获的源标签,则容器为空。
     */
    UFUNCTION(BlueprintCallable, Category = "Ability|GameplayEffect")
    const FGameplayTagContainer& GetSourceSpecTags(const FGameplayEffectSpec& EffectSpec) const;

    /**
     * 从游戏玩法效果规格中复制并返回目标聚合标签。
     *
     * @param EffectSpec 从中获取信息的游戏玩法效果规格
     * 
     * @return 包含复制标签的游戏玩法标签容器。如果不存在捕获的源标签,则容器为空。
     */
    UFUNCTION(BlueprintCallable, BlueprintPure = false, Category = "Ability|GameplayEffect")
    FGameplayTagContainer GetTargetAggregatedTags(const FGameplayEffectSpec& EffectSpec) const;

    /**
     * 从游戏玩法效果规格中返回目标 Actor 标签。
     * 对修饰符幅度计算很有用。
     *
     * @param EffectSpec 从中获取信息的游戏玩法效果规格
     * 
     * @return 包含复制标签的游戏玩法标签容器。如果不存在捕获的源标签,则容器为空。
     */
    UFUNCTION(BlueprintCallable, Category = "Ability|GameplayEffect")
    const FGameplayTagContainer& GetTargetActorTags(const FGameplayEffectSpec& EffectSpec) const;

    /**
     * 从游戏玩法效果规格中返回目标规格标签。
     * 对修饰符幅度计算很有用。
     *
     * @param EffectSpec 从中获取信息的游戏玩法效果规格
     * 
     * @return 包含复制标签的游戏玩法标签容器。如果不存在捕获的源标签,则容器为空。
     */
    UFUNCTION(BlueprintCallable, Category = "Ability|GameplayEffect")
    const FGameplayTagContainer& GetTargetSpecTags(const FGameplayEffectSpec& EffectSpec) const;
};

 

posted @ 2025-02-24 00:01  mcwhirr  阅读(39)  评论(0)    收藏  举报