小工具知识网

当前位置: 首页 > 行业知识 > 第6章---GameplayTag初识以及拾起物品UI制作

行业知识

第6章---GameplayTag初识以及拾起物品UI制作

2026-11-09 03:30:52 来源:互联网转载

文件结构

Source

()
  • Private
    • AbilitySystemComponen
      • RPGAbilitySystemComponent.cpp
      • RPGAttributeSet.cpp
      • Character
        • PGGameCharacterBase.cpp
        • RPGGameEnemy.cpp
        • RPGGamePlayerCharacter.cpp
        • Game
          • RPGGameModeBase.cpp
          • Interaction
            • EnemyInterface.cpp
            • Player
              • RPGPlayerController.cpp
              • RPGPlayerState.cpp
              • Actor
                • RPGEffectActor.cpp
                • UI
                  • HUD
                    • RPGHUD.cpp
                    • WidgetController
                      • OverlayWidgetController.cpp
                      • RPGWidgetController.cpp
                      • Widgets
                        • RPGUserWidget.cpp
                        • Public
                          • AbilitySystemComponent
                            • RPGAbilitySystemComponent.h
                            • RPGAttributeSet.h
                            • Character
                              • RPGGameCharacterBase.h
                              • RPGGameEnemy.h
                              • RPGGamePlayerCharacter.h
                              • Game
                                • RPGGameModeBase.h
                                • Interaction
                                  • EnemyInterface.h
                                  • Player
                                    • RPGPlayerController.h
                                    • RPGPlayerState.h
                                    • Actor
                                      • RPGEffectActor.h
                                      • UI
                                        • HUD
                                          • RPGHUD.h
                                          • WidgetController
                                            • OverlayWidgetController.h
                                            • RPGWidgetController.h
                                            • Widgets
                                              • RPGUserWidget.h

                                                文件概述

                                                RPGAbilitySystemComponent

                                                .h文件
                                                // Copyright KimiLiu#pragma once#include "CoreMinimal.h"#include "AbilitySystemComponent.h"#include "RPGAbilitySystemComponent.generated.h"DECLARE_MULTICAST_DELEGATE_OneParam(FEffectAssetTags, const FGameplayTagContainer&/*AssetTags*/);/** * Ability System Component 拥有两个Owner: Owner Actor 以及Avatar Actor,这两个Actor有可能相同,有可能不相同 *  Owner Actor 指的是实例化组件的Actor *  Avatar Actor 指的是ASC实际上服务的Actor,例如 *     - RPGGameEnemy 内的ASC的 Owner Actor 和 Avatar Actor 都是 RPGGameEnemy 这个 Actor 类自身。因为ASC由 RPGGameEnemy 实例 *        化,同时服务于 RPGGameEnemy *     - RPGGamePlayerCharacter 内的ASC的 Owner Actor 是 RPGPlayerState,而 Avatar Actor 是RPGGamePlayerCharacter。因为 *        ASC由RPGPlayerState实例化,但是ASC服务于PRGGamePlayerCharacter */UCLASS()class AURA_API URPGAbilitySystemComponent : public UAbilitySystemComponent{    GENERATED_BODY()public:    // ASC初始化完成(设置了实际所有者以及逻辑所有者)    void AbilityActorInfoSet();    //     FEffectAssetTags EffectAssetTags;protected:    // 当有任何GE在自身上被应用时会触发委托调用该函数    void EffectApplied(UAbilitySystemComponent* AbilitySystemComponent, const FGameplayEffectSpec& GameplayEffectSpec, FActiveGameplayEffectHandle ActiveGameplayEffectHandle);    };
                                                .cpp文件
                                                // Copyright KimiLiu#include "AbilitySytstem/RPGAbilitySystemComponent.h"void URPGAbilitySystemComponent::AbilityActorInfoSet(){    // 绑定委托    OnGameplayEffectAppliedDelegateToSelf.AddUObject(this, &URPGAbilitySystemComponent::EffectApplied);}void URPGAbilitySystemComponent::EffectApplied(UAbilitySystemComponent* AbilitySystemComponent,    const FGameplayEffectSpec& GameplayEffectSpec, FActiveGameplayEffectHandle ActiveGameplayEffectHandle){    //GEngine->AddOnScreenDebugMessage(1, 5.f, FColor::Red, FString("Effect Applied"));        FGameplayTagContainer TagContainer;    GameplayEffectSpec.GetAllAssetTags(TagContainer);    // 广播    EffectAssetTags.Broadcast(TagContainer);        }

                                                RPGAttributeSet

                                                .h文件
                                                // Copyright KimiLiu#pragma once#include "CoreMinimal.h"#include "AbilitySystemComponent.h"#include "AttributeSet.h"#include "RPGAttributeSet.generated.h"#define ATTRIBUTE_ACCESSORS(ClassName, PropertyName) \    GAMEPLAYATTRIBUTE_PROPERTY_GETTER(ClassName, PropertyName) \    GAMEPLAYATTRIBUTE_VALUE_GETTER(PropertyName) \    GAMEPLAYATTRIBUTE_VALUE_SETTER(PropertyName) \    GAMEPLAYATTRIBUTE_VALUE_INITTER(PropertyName)// 逻辑处理数据结构,在这个结构中能够获取目标ASC以及源头ASC,以及目标对象,源头对象,目标控制器,源头控制器USTRUCT()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;};/** * AS拥有预测功能(Prediction)能够让多人游戏的客户端在拥有更少的延迟。客户端能够立刻改变自己维护的AS,然后通知服务端,由服务端判定这个更 *  改是否合法,如果不合法,则服务端拒绝更改AS并通知客户端回滚AS */UCLASS()class AURA_API URPGAttributeSet : public UAttributeSet{    GENERATED_BODY()public:    URPGAttributeSet();    //复制变量时必须重写的函数,用于注册需要复制的变量    virtual void GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const override;        //在属性被更改前调用,不用来处理逻辑,只用来限制值大小    virtual void PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue) override;    //在属性被更改后调用,用来处理逻辑    virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;    /**     * 创建AS属性步骤:     * 1. 声明FGameplayAttributeData类型变量     * 2. 用UPROPERTY()宏修饰     * 3. 如果是多人游戏,需要在宏内声明: ReplicatedUsing = OnRep_属性名,同时声明一个UFUNCTION()方法OnRep_属性名()。当服务端的该属性     *    值变化时,OnRep_属性名()将会被调用,我们在这个函数内处理变化事件     * 4. 实现OnRep_属性名()函数,在函数内调用GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, 属性名, 旧属性值)宏,用来保存旧值用于     *    服务端通知客户端进行回滚     * 5. 重写GetLifetimeReplicatedProps()函数,在该函数内注册属性     * 6. 使用ATTRIBUTE_ACCESSORS()宏来初始化value_getter, property_getter, value_setter, initter     */        UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Health, Category="Vital Attribute")    FGameplayAttributeData Health;    ATTRIBUTE_ACCESSORS(URPGAttributeSet, Health);    UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_MaxHealth, Category="Vital Attribute")    FGameplayAttributeData MaxHealth;    ATTRIBUTE_ACCESSORS(URPGAttributeSet, MaxHealth);        UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Mana, Category="Vital Attribute")    FGameplayAttributeData Mana;    ATTRIBUTE_ACCESSORS(URPGAttributeSet, Mana);    UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_Mana, Category="Vital Attribute")    FGameplayAttributeData MaxMana;    ATTRIBUTE_ACCESSORS(URPGAttributeSet, MaxMana);    UFUNCTION()    void OnRep_Health(const FGameplayAttributeData& OldHealth) const;    UFUNCTION()    void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const ;    UFUNCTION()    void OnRep_Mana(const FGameplayAttributeData& OldMana) const;    UFUNCTION()    void OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const;private:    //设置FEffectProperties类数据,Props内有很多信息,参照上面的结构体声明    void SetEffectProperties(const FGameplayEffectModCallbackData& Data, FEffectProperties& Props) const;};
                                                .cpp文件
                                                // Copyright KimiLiu#include "AbilitySytstem/RPGAttributeSet.h"#include "AbilitySystemBlueprintLibrary.h"#include "Net/UnrealNetwork.h"#include "GameplayEffectExtension.h"#include "GameFramework/Character.h"URPGAttributeSet::URPGAttributeSet(){    InitHealth(50.f);    InitMaxHealth(100.f);    InitMana(50.f);    InitMaxMana(100.f);}void URPGAttributeSet::GetLifetimeReplicatedProps(TArray& OutLifetimeProps) const{    Super::GetLifetimeReplicatedProps(OutLifetimeProps);    //注册需要复制的属性Health,没有复制条件,不论复制的结果是否等于客户端原有结果,都进行复制调用    DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, Health, COND_None, REPNOTIFY_Always);    DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);    DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, Mana, COND_None, REPNOTIFY_Always);    DOREPLIFETIME_CONDITION_NOTIFY(URPGAttributeSet, MaxMana, COND_None, REPNOTIFY_Always);}// 此处的Clamp只能更改CurrentValue,不能更改BaseValue,因此还需要在Post函数中做一次Clampvoid URPGAttributeSet::PreAttributeChange(const FGameplayAttribute& Attribute, float& NewValue){    Super::PreAttributeChange(Attribute, NewValue);    if (Attribute == GetHealthAttribute())    {       NewValue = FMath::Clamp(NewValue, 0.f, GetMaxHealth());    }    if (Attribute == GetMaxHealthAttribute())    {           }    if (Attribute == GetManaAttribute())    {       NewValue = FMath::Clamp(NewValue, 0.f, GetMaxMana());    }    if (Attribute == GetMaxManaAttribute())    {           }}void URPGAttributeSet::SetEffectProperties(const FGameplayEffectModCallbackData& Data, FEffectProperties& Props) const{    // Source = causer of the effect, Target = target of the effect (owner of this AS)    // 拿到源头的上下文,上下文内拥有指向ASC的指针    Props.EffectContextHandle = Data.EffectSpec.GetContext();    Props.SourceASC = Props.EffectContextHandle.GetOriginalInstigatorAbilitySystemComponent();    if (IsValid(Props.SourceASC) && Props.SourceASC->AbilityActorInfo.IsValid() && Props.SourceASC->AbilityActorInfo->AvatarActor.IsValid())    {       // 获取逻辑拥有者       Props.SourceAvatarActor = Props.SourceASC->AbilityActorInfo->AvatarActor.Get();       // 获取控制器       Props.SourceController = Props.SourceASC->AbilityActorInfo->PlayerController.Get();       // 若ASC组件没有控制器,则从逻辑拥有者那里获取控制器       if (Props.SourceController == nullptr && Props.SourceAvatarActor != nullptr)       {          // Source有可能没有Controller          if (const APawn* Pawn = Cast(Props.SourceAvatarActor))          {             Props.SourceAvatarActor = Pawn->GetController();          }       }       // 获取来源角色       if (Props.SourceController)       {          Props.SourceCharacter = Cast(Props.SourceController->GetPawn());       }    }    // 拿到目标Actor    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(Props.TargetAvatarActor);       Props.TargetASC = UAbilitySystemBlueprintLibrary::GetAbilitySystemComponent(Props.TargetAvatarActor);    }}// Data 很强大,我们可以从中拿到任何我们想拿到的东西,但是得注意是否是空指针,需要做判断void URPGAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data){    Super::PostGameplayEffectExecute(Data);    // Source = causer of the effect, Target = target of the effect (owner of this AS)    FEffectProperties Props;    SetEffectProperties(Data, Props);    // 可以用Prps来取到我们想要的值,处理大部分逻辑    if (Data.EvaluatedData.Attribute == GetHealthAttribute())    {       GEngine->AddOnScreenDebugMessage(1, 3.f, FColor::Red, FString::Printf(TEXT("Health: %f"), GetHealth()));       SetHealth(FMath::Clamp(GetHealth(), 0.f, GetMaxHealth()));    }    if (Data.EvaluatedData.Attribute == GetManaAttribute())    {       GEngine->AddOnScreenDebugMessage(1, 3.f, FColor::Blue, FString::Printf(TEXT("Mana: %f"), GetHealth()));       SetMana(FMath::Clamp(GetMana(), 0.f, GetMaxMana()));    }        }void URPGAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) const {    // 当Health属性被调用,此函数被调用,传入OldHealth作为旧值,该旧值将会被保存以免服务端通知客户端该属性需要回滚    GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, Health, OldHealth);}void URPGAttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const {    GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, Health, OldMaxHealth);}void URPGAttributeSet::OnRep_Mana(const FGameplayAttributeData& OldMana) const{    GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, Mana, OldMana);}void URPGAttributeSet::OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const{    GAMEPLAYATTRIBUTE_REPNOTIFY(URPGAttributeSet, MaxMana, OldMaxMana);}

                                                OverlayWidgetController

                                                .h文件
                                                // Copyright KimiLiu#pragma once#include "CoreMinimal.h"#include "AbilitySytstem/RPGAttributeSet.h"#include "UI/WidgetController/RPGWidgetController.h"#include "OverlayWidgetController.generated.h"USTRUCT(BlueprintType)struct FUIWidgetRow : public FTableRowBase{    GENERATED_BODY()    UPROPERTY(EditAnywhere, BlueprintReadOnly)    FGameplayTag MessageTag = FGameplayTag();        UPROPERTY(EditAnywhere, BlueprintReadOnly)    FText Message = FText();    UPROPERTY(EditAnywhere, BlueprintReadOnly)    TSubclassOf MessageData;    UPROPERTY(EditAnywhere, BlueprintReadOnly)    UTexture2D* Image = nullptr;};class URPGUserWidget;DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FOnAttributeChangeSignature, float, NewValue);DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMessageWidgetRowSignature, FUIWidgetRow, Row);/** *  */UCLASS(BlueprintType, Blueprintable)class AURA_API UOverlayWidgetController : public URPGWidgetController{    GENERATED_BODY()public:    virtual void BroadcastInitialValues() override;    virtual void BindCallbacksToDependences() override;    UPROPERTY(BlueprintAssignable, Category="GAS|Attribute")    FOnAttributeChangeSignature OnHealthChanged;    UPROPERTY(BlueprintAssignable, Category="GAS|Attribute")    FOnAttributeChangeSignature OnMaxHealthChanged;    UPROPERTY(BlueprintAssignable, Category="GAS|Attribute")    FOnAttributeChangeSignature OnManaChanged;    UPROPERTY(BlueprintAssignable, Category="GAS|Attribute")    FOnAttributeChangeSignature OnMaxManaChanged;    UPROPERTY(BlueprintAssignable, Category="GAS|Messages")    FMessageWidgetRowSignature MessageWidgetRowDelegate;protected:    UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category="Widget Data")    TObjectPtr MessageWidgetDataTable;        // ~Start Delegate Function    // ~End Delegate Function        // 自定义带的模板函数,以后可以常用,指定父类可以获得多个子类的相关函数    template     T* GetDataTableRowByTag(UDataTable* DataTable, const FGameplayTag& Tag);    };// 模板函数实现template T* UOverlayWidgetController::GetDataTableRowByTag(UDataTable* DataTable, const FGameplayTag& Tag){    T* Row = DataTable->FindRow(Tag.GetTagName(), TEXT(""));    return Row;}
                                                .cpp文件

                                                .AddLambda可以把函数直接写在()内,不需要多写一个函数,方便了很多,可以后期一次性看到我们绑定的函数是啥,以及这个函数干嘛用的

                                                // Copyright KimiLiu#include "UI/WidgetController/OverlayWidgetController.h"#include "AbilitySytstem/RPGAbilitySystemComponent.h"#include "AbilitySytstem/RPGAttributeSet.h"//初始化多播执行事件void UOverlayWidgetController::BroadcastInitialValues(){    //父类的AttributeSet类型是UAttributeSet不是RPGAttributeSet需要自行Cast    const URPGAttributeSet* RPGAttributeSet = CastChecked(AttributeSet);    //执行初始化多播通知    OnHealthChanged.Broadcast(RPGAttributeSet->GetHealth());    OnMaxHealthChanged.Broadcast(RPGAttributeSet->GetMaxHealth());    OnManaChanged.Broadcast(RPGAttributeSet->GetMana());    OnMaxManaChanged.Broadcast(RPGAttributeSet->GetMaxMana());    }// 绑定(注册)Attribute改变事件,当Attribute的基础值改变的时候,会执行相应Attribute的对应的函数void UOverlayWidgetController::BindCallbacksToDependences(){    const URPGAttributeSet* RPGAttributeSet = CastChecked(AttributeSet);    AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(       RPGAttributeSet->GetHealthAttribute()).AddLambda(       [this](const FOnAttributeChangeData& Data)          {             OnHealthChanged.Broadcast(Data.NewValue);          }       );    AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(       RPGAttributeSet->GetMaxHealthAttribute()).AddLambda(       [this](const FOnAttributeChangeData& Data)          {             OnMaxHealthChanged.Broadcast(Data.NewValue);          }       );    AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(       RPGAttributeSet->GetManaAttribute()).AddLambda(       [this](const FOnAttributeChangeData& Data)          {             OnManaChanged.Broadcast(Data.NewValue);          }       );    AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(       RPGAttributeSet->GetMaxManaAttribute()).AddLambda(       [this](const FOnAttributeChangeData& Data)          {             OnMaxManaChanged.Broadcast(Data.NewValue);          }       );    Cast(AbilitySystemComponent)->EffectAssetTags.AddLambda(       [this](const FGameplayTagContainer& AssetTags)       {          for(FGameplayTag Tag : AssetTags)          {             // "A.1".MatchesTag("A") will return True, "A".MatchesTag("A.1") will return False             FGameplayTag MessageTag = FGameplayTag::RequestGameplayTag(FName("Message"));             if (Tag.MatchesTag(MessageTag))             {                FUIWidgetRow* Row = GetDataTableRowByTag(MessageWidgetDataTable, Tag);                MessageWidgetRowDelegate.Broadcast(*Row);             }          }       }    );}// ~Delegate Function Start // ~Delegate Function End
                                                ()

上一篇:红警ol怎么加入服务器?

下一篇:宝塔面板怎么更改配置?