添加一些新的属性
添加一些新的属性
UCLASS()
class UCAttributeSet : public UAttributeSet
{
// 攻击力
UPROPERTY(ReplicatedUsing = OnRep_AttackDamage)
FGameplayAttributeData AttackDamage;
ATTRIBUTE_ACCESSORS(UCAttributeSet, AttackDamage)
// 护甲值
UPROPERTY(ReplicatedUsing = OnRep_Armor)
FGameplayAttributeData Armor;
ATTRIBUTE_ACCESSORS(UCAttributeSet, Armor)
// 移动速度
UPROPERTY(ReplicatedUsing = OnRep_MoveSpeed)
FGameplayAttributeData MoveSpeed;
ATTRIBUTE_ACCESSORS(UCAttributeSet, MoveSpeed)
// 移动加速度
UPROPERTY(ReplicatedUsing = OnRep_MoveAcceleration)
FGameplayAttributeData MoveAcceleration;
ATTRIBUTE_ACCESSORS(UCAttributeSet, MoveAcceleration)
UFUNCTION()
void OnRep_AttackDamage(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_Armor(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_MoveSpeed(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_MoveAcceleration(const FGameplayAttributeData& OldValue);
};
void UCAttributeSet::GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, Health, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, Mana, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, MaxMana, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, AttackDamage, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, Armor, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, MoveSpeed, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCAttributeSet, MoveAcceleration, COND_None, REPNOTIFY_Always);
}
void UCAttributeSet::OnRep_AttackDamage(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCAttributeSet, AttackDamage, OldValue);
}
void UCAttributeSet::OnRep_Armor(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCAttributeSet, Armor, OldValue);
}
void UCAttributeSet::OnRep_MoveSpeed(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCAttributeSet, MoveSpeed, OldValue);
}
void UCAttributeSet::OnRep_MoveAcceleration(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCAttributeSet, MoveAcceleration, OldValue);
}
再创建一个玩家角色用的属性
// 幻雨喜欢小猫咪
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "AbilitySystemComponent.h"
#include "CHeroAttributeSet.generated.h"
// 属性访问器宏,自动生成属性的Getter/Setter等
#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \
GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)
/**
* 英雄属性集(UCHeroAttributeSet)
* 用于管理英雄的成长属性、经验、等级、升级点、金币等
* 支持属性同步、属性变化回调等功能
*/
UCLASS()
class UCHeroAttributeSet : public UAttributeSet
{
GENERATED_BODY()
public:
// 属性访问器声明(自动生成标准接口)
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, Intelligence) // 智力
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, Strength) // 力量
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, Experience) // 当前经验
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, PrevLevelExperience) // 上一级所需经验
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, NextLevelExperience) // 下一级所需经验
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, Level) // 当前等级
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, UpgradePoint) // 可用升级点
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, MaxLevel) // 最大等级
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, MaxLevelExperience) // 满级所需经验
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, Gold) // 金币
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, StrengthGrowthRate) // 力量成长率
ATTRIBUTE_ACCESSORS(UCHeroAttributeSet, IntelligenceGrowthRate) // 智力成长率
// 属性同步(网络复制)配置
virtual void GetLifetimeReplicatedProps( TArray< class FLifetimeProperty > & OutLifetimeProps ) const override;
private:
// 智力
UPROPERTY(ReplicatedUsing = OnRep_Intelligence)
FGameplayAttributeData Intelligence;
// 力量
UPROPERTY(ReplicatedUsing = OnRep_Strength)
FGameplayAttributeData Strength;
// 当前经验
UPROPERTY(ReplicatedUsing = OnRep_Experience)
FGameplayAttributeData Experience;
// 力量成长率
UPROPERTY()
FGameplayAttributeData StrengthGrowthRate;
// 智力成长率
UPROPERTY()
FGameplayAttributeData IntelligenceGrowthRate;
// 上一级所需经验
UPROPERTY(ReplicatedUsing = OnRep_PrevLevelExperience)
FGameplayAttributeData PrevLevelExperience;
// 下一级所需经验
UPROPERTY(ReplicatedUsing = OnRep_NextLevelExperience)
FGameplayAttributeData NextLevelExperience;
// 当前等级
UPROPERTY(ReplicatedUsing = OnRep_Level)
FGameplayAttributeData Level;
// 可用升级点
UPROPERTY(ReplicatedUsing = OnRep_UpgradePoint)
FGameplayAttributeData UpgradePoint;
// 最大等级
UPROPERTY(ReplicatedUsing = OnRep_MaxLevel)
FGameplayAttributeData MaxLevel;
// 满级所需经验
UPROPERTY(ReplicatedUsing = OnRep_MaxLevelExperience)
FGameplayAttributeData MaxLevelExperience;
// 金币
UPROPERTY(ReplicatedUsing = OnRep_Gold)
FGameplayAttributeData Gold;
// 属性同步回调(用于客户端属性变化通知)
UFUNCTION()
void OnRep_Intelligence(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_Strength(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_Experience(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_PrevLevelExperience(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_NextLevelExperience(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_Level(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_UpgradePoint(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_MaxLevel(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_MaxLevelExperience(const FGameplayAttributeData& OldValue);
UFUNCTION()
void OnRep_Gold(const FGameplayAttributeData& OldValue);
};
// 幻雨喜欢小猫咪
#include "GAS/Core/CHeroAttributeSet.h"
#include "Net/UnrealNetwork.h"
#include "GameplayEffectExtension.h"
void UCHeroAttributeSet::GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const
{
Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, Intelligence, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, Strength, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, Experience, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, PrevLevelExperience, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, NextLevelExperience, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, Level, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, UpgradePoint, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, MaxLevel, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, MaxLevelExperience, COND_None, REPNOTIFY_Always);
DOREPLIFETIME_CONDITION_NOTIFY(UCHeroAttributeSet, Gold, COND_None, REPNOTIFY_Always);
}
void UCHeroAttributeSet::OnRep_Intelligence(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, Intelligence, OldValue);
}
void UCHeroAttributeSet::OnRep_Strength(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, Strength, OldValue);
}
void UCHeroAttributeSet::OnRep_Experience(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, Experience, OldValue);
}
void UCHeroAttributeSet::OnRep_PrevLevelExperience(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, PrevLevelExperience, OldValue);
}
void UCHeroAttributeSet::OnRep_NextLevelExperience(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, NextLevelExperience, OldValue);
}
void UCHeroAttributeSet::OnRep_Level(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, Level, OldValue);
}
void UCHeroAttributeSet::OnRep_UpgradePoint(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, UpgradePoint, OldValue);
}
void UCHeroAttributeSet::OnRep_MaxLevel(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, MaxLevel, OldValue);
}
void UCHeroAttributeSet::OnRep_MaxLevelExperience(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, MaxLevelExperience, OldValue);
}
void UCHeroAttributeSet::OnRep_Gold(const FGameplayAttributeData& OldValue)
{
GAMEPLAYATTRIBUTE_REPNOTIFY(UCHeroAttributeSet, Gold, OldValue);
}
在玩家角色中创建该属性集
#pragma region Gameplay Ability
private:
// 瞄准状态变化时回调
virtual void OnAimStateChanged(bool bIsAiming) override;
UPROPERTY()
TObjectPtr<UCHeroAttributeSet> HeroAttributeSet;
#pragma endregion
在构造函数中创建该属性集
ACPlayerCharacter::ACPlayerCharacter()
{
HeroAttributeSet = CreateDefaultSubobject<UCHeroAttributeSet>(TEXT("HeroAttributeSet"));
}
创新一个UI用来显示属性
创建一个StatsGauge
将属性传入过去显示
// 幻雨喜欢小猫咪
#pragma once
#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "Blueprint/UserWidget.h"
#include "GameplayEffectTypes.h"
#include "Components/Image.h"
#include "Components/TextBlock.h"
#include "StatsGauge.generated.h"
/**
* 绑定属性数值的UI
*/
UCLASS()
class CRUNCH_API UStatsGauge : public UUserWidget
{
GENERATED_BODY()
public:
// 构建前
virtual void NativePreConstruct() override;
// 构建时
virtual void NativeConstruct() override;
private:
// 属性图标控件
UPROPERTY(meta=(BindWidget))
TObjectPtr<UImage> Icon;
// 属性数值文本控件
UPROPERTY(meta=(BindWidget))
TObjectPtr<UTextBlock> AttributeText;
// 需要显示的属性
UPROPERTY(EditAnywhere, Category = "Attribute")
FGameplayAttribute Attribute;
// 图标资源
UPROPERTY(EditAnywhere, Category = "Visual")
TObjectPtr<UTexture2D> IconTexture;
// 设置属性数值显示
void SetValue(float NewVal);
// 数字格式化选项
FNumberFormattingOptions NumberFormattingOptions;
// 属性变化回调
void AttributeChanged(const FOnAttributeChangeData& Data);
};
// 幻雨喜欢小猫咪
#include "UI/Gameplay/StatsGauge.h"
#include "AbilitySystemBlueprintLibrary.h"
#include "AbilitySystemComponent.h"
void UStatsGauge::NativePreConstruct()
{
Super::NativePreConstruct();
Icon->SetBrushFromTexture(IconTexture);
}
void UStatsGauge::NativeConstruct()
{
Super::NativeConstruct();
// 设置为整数格式
NumberFormattingOptions.MaximumFractionalDigits = 0;
APawn* OwnerPlayerPawn = GetOwningPlayerPawn();
if (!OwnerPlayerPawn) return;
UAbilitySystemComponent* OwnerASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(OwnerPlayerPawn);
if (OwnerASC)
{
bool bFound;
float AttributeValue = OwnerASC->GetGameplayAttributeValue(Attribute, bFound);
if (bFound)
{
SetValue(AttributeValue);
}
OwnerASC->GetGameplayAttributeValueChangeDelegate(Attribute).AddUObject(this, &UStatsGauge::AttributeChanged);
}
}
void UStatsGauge::SetValue(float NewVal)
{
AttributeText->SetText(FText::AsNumber(NewVal, &NumberFormattingOptions));
}
void UStatsGauge::AttributeChanged(const FOnAttributeChangeData& Data)
{
SetValue(Data.NewValue);
}
将属性UI放到游戏界面中,在GameplayWidget
中添加几个属性UI
// 属性面板:攻击力显示控件
UPROPERTY(meta=(BindWidget))
TObjectPtr<UStatsGauge> AttackDamageGauge;
// 属性面板:护甲显示控件
UPROPERTY(meta=(BindWidget))
TObjectPtr<UStatsGauge> ArmorGauge;
// 属性面板:移动速度显示控件
UPROPERTY(meta=(BindWidget))
TObjectPtr<UStatsGauge> MoveSpeedGauge;
// 属性面板:智力显示控件
UPROPERTY(meta=(BindWidget))
TObjectPtr<UStatsGauge> IntelligenceGauge;
// 属性面板:力量显示控件
UPROPERTY(meta=(BindWidget))
TObjectPtr<UStatsGauge> StrengthGauge;
在蓝图中继承UI,并显示UI
去到UE中创建蓝图版本的属性UI,再将其添加到GameplayWidget中去
添加一个边界作为底色