虚幻引擎5 GAS开发俯视角RPG游戏 P06-31 映射标签到属性
1.在小部件里添加标签,当标签一致时,修改对应的结果:


细节:



2.在属性集里添加映射CC_AttributeSet.h
Map(标签, 获取属性的方法指针)
/** 模板函数:* 别名: 静态函数指针* 用途: 1. TMap(指针,属性)*/
template<class T>
using TStaticFuncPtr = typename TBaseStaticDelegateInstance<T, FDefaultDelegateUserPolicy>::FFuncPtr;
	/** TMap(指针,属性)*/TMap<FGameplayTag, TStaticFuncPtr<FGameplayAttribute()>> TagsToAttributes;
这段代码定义了虚幻引擎5 GAS系统中用于将游戏标签映射到属性访问函数的类型声明。
TStaticFuncPtr是一个模板别名,它指向TBaseStaticDelegateInstance的静态函数指针类型FFuncPtr,这是UE委托系统中用于绑定静态函数的核心类型。
TagsToAttributes是一个TMap容器,键为FGameplayTag游戏标签,值为返回FGameplayAttribute的静态函数指针。这种设计允许通过游戏标签动态查找对应的属性访问函数,为属性菜单UI提供数据支持。
在属性集构造函数里添加映射CC_AttributeSet.cpp:
UCC_AttributeSet::UCC_AttributeSet()
{TagsToAttributes.Add(CC_GameplayTags::Attributes_Primary_Agile, GetAgileAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Primary_Intelligence, GetIntelligenceAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Primary_Strength, GetStrengthAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Primary_Vigor, GetVigorAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_Armor, GetArmorAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_ArmorPenetration, GetArmorPenetrationAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_BlockChance, GetBlockChanceAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_CriticalHitChance, GetCriticalHitChanceAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_CriticalHitDamage, GetCriticalHitDamageAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_CriticalHitResistance, GetCriticalHitResistanceAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_HealthRegeneration, GetHealthRegenerationAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_ManaRegeneration, GetManaRegenerationAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_MaxHealth, GetMaxHealthAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_MaxMana, GetMaxManaAttribute);}3.在CC_AttributeMenuWidgetController.cpp的BroadcastInitialValues方法里:
void UCC_AttributeMenuWidgetController::BroadcastInitialValues()
{if (CC_AttributeSet == nullptr){CC_AttributeSet = CastChecked<UCC_AttributeSet>(AttributeSet);}checkf(AttributeInfo, TEXT("在[%s]中没有配置AttributeInfo"), *GetNameSafe(this));for (auto& Pair : CC_AttributeSet->TagsToAttributes){FAttributeInfo Info = AttributeInfo->FindAttributeInfoFromTag(Pair.Key);Info.AttributeValue = Pair.Value().GetNumericValue(CC_AttributeSet);OnAttributeInfoSignature.Broadcast(Info);}
}这段代码实现了虚幻引擎5 GAS中属性菜单小部件控制器的初始值广播功能。
首先检查属性集是否为空,如果为空则通过类型转换获取属性集实例。接着验证AttributeInfo数据资产是否有效,如果未配置则会触发断言错误。
核心逻辑是遍历属性集中的TagsToAttributes映射,为每个属性标签查找对应的属性信息配置。通过GetNumericValue方法获取属性集的当前数值,并将其设置到属性信息结构中。最后通过OnAttributeInfoSignature委托广播更新后的属性信息,通知UI组件进行相应更新。
该函数通常在WidgetController初始化时调用,确保UI能够正确显示所有属性的初始数值。
效果:

源码:
Source/CC_Aura/Public/AbilitySystem/CC_AttributeSet.h:
// 版权归陈超所有#pragma once#include "CoreMinimal.h"
#include "AbilitySystemComponent.h"
#include "AttributeSet.h"
#include "CC_AttributeSet.generated.h"/*要在游戏中使用它,您可以定义类似这样的内容,然后根据需要添加特定于游戏的功能:*/
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)/*用于存储施放GE的相关对象和目标的相关对象*/
#pragma region FEffectPropertiesUSTRUCT()
struct FEffectProperties
{GENERATED_BODY()FEffectProperties(){}FGameplayEffectContextHandle EffectContextHandle;UPROPERTY()UAbilitySystemComponent* SourceASC = nullptr;UPROPERTY()AActor* SourceAvatarActor = nullptr;UPROPERTY()AController* SourceController = nullptr;UPROPERTY()ACharacter* SourceCharacter = nullptr;UPROPERTY()UAbilitySystemComponent* TargetASC = nullptr;UPROPERTY()AActor* TargetAvatarActor = nullptr;UPROPERTY()AController* TargetController = nullptr;UPROPERTY()ACharacter* TargetCharacter = nullptr;
};#pragma endregion/** 模板函数:* 别名: 静态函数指针* 用途: 1. TMap(指针,属性)*/
template<class T>
using TStaticFuncPtr = typename TBaseStaticDelegateInstance<T, FDefaultDelegateUserPolicy>::FFuncPtr;/*** */
UCLASS()
class CC_AURA_API UCC_AttributeSet : public UAttributeSet
{GENERATED_BODY()public:UCC_AttributeSet();//属性更改前的方法virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;//属性更改后的方法virtual void PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data) override;/** TMap(指针,属性)*/TMap<FGameplayTag, TStaticFuncPtr<FGameplayAttribute()>> TagsToAttributes;private:void SetEffectProperties(const struct FGameplayEffectModCallbackData& Data, FEffectProperties& Props) const;
/**************************************************************************************************************/
/**                                                     添加属性                                               **/
/**************************************************************************************************************/
public:// 用于声明哪些变量需要在服务器和客户端之间自动复制virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;/*Vital属性:
*		1.获取角色等级
*/
#pragma region Vital AttributesUPROPERTY(BlueprintReadOnly, Category="Attributes|Vital", ReplicatedUsing = OnRep_Health)FGameplayAttributeData Health;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, Health);UPROPERTY(BlueprintReadOnly, Category="Attributes|Vital", ReplicatedUsing = OnRep_Mana)FGameplayAttributeData Mana;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, Mana);#pragma endregion/**********************************************************************//*主要属性*1. Vigor: 体质*2. Agile: 敏捷*3. Strength: 力量*4. Intelligence: 智力
*/
#pragma region Primary AttributesUPROPERTY(BlueprintReadOnly, Category="Attributes|Primary", ReplicatedUsing = OnRep_Vigor)FGameplayAttributeData Vigor;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, Vigor);UPROPERTY(BlueprintReadOnly, Category="Attributes|Primary", ReplicatedUsing = OnRep_Agile)FGameplayAttributeData Agile;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, Agile);UPROPERTY(BlueprintReadOnly, Category="Attributes|Primary", ReplicatedUsing = OnRep_Strength)FGameplayAttributeData Strength;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, Strength);UPROPERTY(BlueprintReadOnly, Category="Attributes|Primary", ReplicatedUsing = OnRep_Intelligence)FGameplayAttributeData Intelligence;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, Intelligence);#pragma endregion/*次要属性:* 1. Armor: 护甲	减少受到的伤害, 提高格挡几率.*		- 受Agile影响** 2. Armor Penetration: 护甲穿透	忽略敌人护甲的百分比, 增加暴击几率.*		- 受Agile影响** 3. Block Chance: 格挡几率		有机会将受到的伤害减半.*		- 受Armor影响** 4. Critical Hit Chance: 暴击几率		有机会获得双倍伤害并获得暴击加成*		- 受Armor Penetration影响** 5. Critical Hit Damage: 暴击伤害		暴击时增加的额外伤害*		- 受Armor Penetration影响** 6. Critical Hit Resistance: 暴击抗性		减少敌人攻击时的暴击几率*		- 受Armor影响** 7. Health Regeneration: 生命回复		每秒回复的生命值*		- 受Vigor影响** 8. Mana Regeneration: 魔法回复		每秒回复的魔法值*		- 受Intelligence影响** 9. Max Health: 最大生命值*		- 受Vigor影响** 10. Max Mana: 最大法力值*		- 受Intelligence影响*/#pragma region Secondary AttributesUPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_Armor)FGameplayAttributeData Armor;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, Armor);UPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_ArmorPenetration)FGameplayAttributeData ArmorPenetration;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, ArmorPenetration);UPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_BlockChance)FGameplayAttributeData BlockChance;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, BlockChance);UPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_CriticalHitChance)FGameplayAttributeData CriticalHitChance;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, CriticalHitChance);UPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_CriticalHitDamage)FGameplayAttributeData CriticalHitDamage;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, CriticalHitDamage);UPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_CriticalHitResistance)FGameplayAttributeData CriticalHitResistance;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, CriticalHitResistance);UPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_HealthRegeneration)FGameplayAttributeData HealthRegeneration;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, HealthRegeneration);UPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_ManaRegeneration)FGameplayAttributeData ManaRegeneration;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, ManaRegeneration);UPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_MaxHealth)FGameplayAttributeData MaxHealth;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, MaxHealth);UPROPERTY(BlueprintReadOnly, Category="Attributes|Secondary", ReplicatedUsing = OnRep_MaxMana)FGameplayAttributeData MaxMana;ATTRIBUTE_ACCESSORS(UCC_AttributeSet, MaxMana);#pragma endregion/********************************************************************** 复制回调函数*/
#pragma region OnRep_FucUFUNCTION()void OnRep_ManaRegeneration(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_HealthRegeneration(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_CriticalHitResistance(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_CriticalHitDamage(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_CriticalHitChance(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_BlockChance(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_ArmorPenetration(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_Armor(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_Health(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_MaxHealth(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_Mana(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_MaxMana(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_Intelligence(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_Agile(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_Strength(const FGameplayAttributeData& OldValue) const;UFUNCTION()void OnRep_Vigor(const FGameplayAttributeData& OldValue) const;#pragma endregion/**************************************************************************************************************/
};
Source/CC_Aura/Private/AbilitySystem/CC_AttributeSet.cpp:
// 版权归陈超所有#include "AbilitySystem/CC_AttributeSet.h"#include "AbilitySystemBlueprintLibrary.h"
#include "CC_GameplayTags.h"
#include "Net/UnrealNetwork.h"
#include "GameplayEffectExtension.h"  // 包含FGameplayEffectModCallbackData定义
#include "GameFramework/Character.h"UCC_AttributeSet::UCC_AttributeSet()
{TagsToAttributes.Add(CC_GameplayTags::Attributes_Primary_Agile, GetAgileAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Primary_Intelligence, GetIntelligenceAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Primary_Strength, GetStrengthAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Primary_Vigor, GetVigorAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_Armor, GetArmorAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_ArmorPenetration, GetArmorPenetrationAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_BlockChance, GetBlockChanceAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_CriticalHitChance, GetCriticalHitChanceAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_CriticalHitDamage, GetCriticalHitDamageAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_CriticalHitResistance, GetCriticalHitResistanceAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_HealthRegeneration, GetHealthRegenerationAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_ManaRegeneration, GetManaRegenerationAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_MaxHealth, GetMaxHealthAttribute);TagsToAttributes.Add(CC_GameplayTags::Attributes_Secondary_MaxMana, GetMaxManaAttribute);}void UCC_AttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue)
{Super::PreAttributeChange(Attribute, NewValue);if (Attribute == GetHealthAttribute()){NewValue = FMath::Clamp(NewValue, 0.f, GetMaxHealth());}if (Attribute == GetManaAttribute()){NewValue = FMath::Clamp(NewValue, 0.f, GetMaxMana());}
}void UCC_AttributeSet::PostGameplayEffectExecute(const struct FGameplayEffectModCallbackData& Data)
{Super::PostGameplayEffectExecute(Data);FEffectProperties Props;SetEffectProperties(Data, Props);if(Data.EvaluatedData.Attribute == GetHealthAttribute()){SetHealth(FMath::Clamp(GetHealth(), 0.f, GetMaxHealth()));}if(Data.EvaluatedData.Attribute == GetManaAttribute()){SetMana(FMath::Clamp(GetMana(), 0.f, GetMaxMana()));}}void UCC_AttributeSet::SetEffectProperties(const struct FGameplayEffectModCallbackData& Data, FEffectProperties& Props) const
{Props.EffectContextHandle = Data.EffectSpec.GetContext();//获取效果所有者的相关对象Props.SourceASC = Props.EffectContextHandle.GetOriginalInstigatorAbilitySystemComponent();	//获取SourceASCif(IsValid(Props.SourceASC) && Props.SourceASC->AbilityActorInfo.IsValid() && Props.SourceASC->AbilityActorInfo->AvatarActor.IsValid()){Props.SourceAvatarActor = Props.SourceASC->AbilityActorInfo->AvatarActor.Get();			//获取SourceAvatarActorProps.SourceController = Props.SourceASC->AbilityActorInfo->PlayerController.Get();		//获取SourceControllerif(Props.SourceController == nullptr && Props.SourceAvatarActor != nullptr){if(const APawn* Pawn = Cast<APawn>(Props.SourceAvatarActor)){Props.SourceController = Pawn->GetController();}}if(Props.SourceController){Props.SourceCharacter = Cast<ACharacter>(Props.SourceController->GetPawn());	//获取SourceCharacter}}if(Data.Target.AbilityActorInfo.IsValid() && Data.Target.AbilityActorInfo->AvatarActor.IsValid()){Props.TargetAvatarActor = Data.Target.AbilityActorInfo->AvatarActor.Get();Props.TargetController = Data.Target.AbilityActorInfo->PlayerController.Get();Props.TargetCharacter = Cast<ACharacter>(Props.TargetAvatarActor);Props.TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(Props.TargetAvatarActor);}	
}//将游戏玩法属性添加到属性集源文件中的GetLifetimeReplicatedProps函数中
void UCC_AttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{Super::GetLifetimeReplicatedProps(OutLifetimeProps);// 为生命值添加复制功能。DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, Health, COND_None, REPNOTIFY_Always);// 为最大生命值添加复制功能。DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);// 为魔法值添加复制功能。DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, Mana, COND_None, REPNOTIFY_Always);// 为最大魔法值添加复制功能。DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, MaxMana, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, Intelligence, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, Agile, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, Strength, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, Vigor, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, Armor, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, ArmorPenetration, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, BlockChance, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, CriticalHitChance, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, CriticalHitDamage, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, CriticalHitResistance, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, HealthRegeneration, COND_None, REPNOTIFY_Always);DOREPLIFETIME_CONDITION_NOTIFY(UCC_AttributeSet, ManaRegeneration, COND_None, REPNOTIFY_Always);}void UCC_AttributeSet::OnRep_ManaRegeneration(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, ManaRegeneration, OldValue);
}void UCC_AttributeSet::OnRep_HealthRegeneration(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, HealthRegeneration, OldValue);
}void UCC_AttributeSet::OnRep_CriticalHitResistance(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, CriticalHitResistance, OldValue);
}void UCC_AttributeSet::OnRep_CriticalHitDamage(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, CriticalHitDamage, OldValue);
}void UCC_AttributeSet::OnRep_CriticalHitChance(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, CriticalHitChance, OldValue);
}void UCC_AttributeSet::OnRep_BlockChance(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, BlockChance, OldValue);
}void UCC_AttributeSet::OnRep_ArmorPenetration(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, ArmorPenetration, OldValue);
}void UCC_AttributeSet::OnRep_Armor(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, Armor, OldValue);
}//~Begin 属性复制回调函数
void UCC_AttributeSet::OnRep_Health(const FGameplayAttributeData& OldValue) const
{// 使用默认的游戏玩法属性系统更新通知行为。GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, Health, OldValue);
}void UCC_AttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldValue) const
{// 使用默认的游戏玩法属性系统更新通知行为。GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, MaxHealth, OldValue);
}void UCC_AttributeSet::OnRep_Mana(const FGameplayAttributeData& OldValue) const
{// 使用默认的游戏玩法属性系统更新通知行为。GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, Mana, OldValue);
}void UCC_AttributeSet::OnRep_MaxMana(const FGameplayAttributeData& OldValue) const
{// 使用默认的游戏玩法属性系统更新通知行为。GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, MaxMana, OldValue);
}void UCC_AttributeSet::OnRep_Intelligence(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, Intelligence, OldValue);
}void UCC_AttributeSet::OnRep_Agile(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, Agile, OldValue);
}void UCC_AttributeSet::OnRep_Strength(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, Strength, OldValue);
}void UCC_AttributeSet::OnRep_Vigor(const FGameplayAttributeData& OldValue) const
{GAMEPLAYATTRIBUTE_REPNOTIFY(UCC_AttributeSet, Vigor, OldValue);
}//~End 属性复制回调函数Source/CC_Aura/Public/UI/WidgetController/CC_AttributeMenuWidgetController.h:
// 版权归陈超所有#pragma once#include "CoreMinimal.h"
#include "UI/WidgetController/CC_WidgetController.h"
#include "CC_AttributeMenuWidgetController.generated.h"class UCC_AttributeInfo;
struct FAttributeInfo;
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAttributeInfoSignature, const FAttributeInfo&, Info);/*** */
UCLASS(Blueprintable)
class CC_AURA_API UCC_AttributeMenuWidgetController : public UCC_WidgetController
{GENERATED_BODY()public://广播初始值virtual void BroadcastInitialValues() override;//依赖的绑定回调函数virtual void BindCallbacksToDependencies() override;protected:UPROPERTY(EditDefaultsOnly, Category="CC|GAS|Attributes")TObjectPtr<UCC_AttributeInfo> AttributeInfo;UPROPERTY(BlueprintAssignable, BlueprintReadWrite, Category="CC|GAS|Attributes")FOnAttributeInfoSignature OnAttributeInfoSignature;};
Source/CC_Aura/Private/UI/WidgetController/CC_AttributeMenuWidgetController.cpp:
// 版权归陈超所有#include "UI/WidgetController/CC_AttributeMenuWidgetController.h"#include "CC_GameplayTags.h"
#include "AbilitySystem/CC_AttributeSet.h"
#include "AbilitySystem/Data/CC_AttributeInfo.h"void UCC_AttributeMenuWidgetController::BroadcastInitialValues()
{if (CC_AttributeSet == nullptr){CC_AttributeSet = CastChecked<UCC_AttributeSet>(AttributeSet);}checkf(AttributeInfo, TEXT("在[%s]中没有配置AttributeInfo"), *GetNameSafe(this));for (auto& Pair : CC_AttributeSet->TagsToAttributes){FAttributeInfo Info = AttributeInfo->FindAttributeInfoFromTag(Pair.Key);Info.AttributeValue = Pair.Value().GetNumericValue(CC_AttributeSet);OnAttributeInfoSignature.Broadcast(Info);}
}void UCC_AttributeMenuWidgetController::BindCallbacksToDependencies()
{//属性发生变化时,希望也进行广播if (CC_AttributeSet == nullptr){CC_AttributeSet = CastChecked<UCC_AttributeSet>(AttributeSet);}checkf(AttributeInfo, TEXT("在[%s]中没有配置AttributeInfo"), *GetNameSafe(this));for (auto& Pair : CC_AttributeSet->TagsToAttributes){AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(Pair.Value()).AddLambda([this, Pair](const FOnAttributeChangeData& Data){FAttributeInfo Info = AttributeInfo->FindAttributeInfoFromTag(Pair.Key);Info.AttributeValue = Pair.Value().GetNumericValue(CC_AttributeSet);OnAttributeInfoSignature.Broadcast(Info);});}}
