c++unreal-engine4unreal-gameplay-ability-system

Unreal GAS: Print out the current value of an attribute to UI when it changes


When the base value of an attribute changes, there is UAttributeSet::PostGameplayEffectExecute() available to access the (new) value and GameplayEffect with its context. I'm using this to print the changed value to UI (this is also done in ActionRPG).

Is there something similar available for the current value of an attribute? How to notify UI, when FGameplayAttributeData::CurrentValue is updated?



Solution

  • The GameplayAbilitySystem has UAbilitySystemComponent::GetGameplayAttributeValueChangeDelegate() which returns a callback of type FOnGameplayAttributeValueChange that is triggered whenever an attribute is changed (base value or current value). This can be used to register a delegate/callback, which can be used to update the UI.

    Minimal example

    In MyCharacter.h

    // Declare the type for the UI callback.
    DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FAttributeChange, float, AttributeValue);
    
    UCLASS()
    class MYPROJECT_API MyCharacter : public ACharacter, public IAbilitySystemInterface
    {
        // ...
    
        // This callback can be used by the UI.
        UPROPERTY(BlueprintAssignable, Category = "Attribute callbacks")
        FAttributeChange OnManaChange;
    
        // The callback to be registered within AbilitySystem.
        void OnManaUpdated(const FOnAttributeChangeData& Data);
    
        // Within here, the callback is registered.
        void BeginPlay() override;
    
        // ...
    }
    

    In MyCharacter.cpp

    void MyCharacter::OnManaUpdated(const FOnAttributeChangeData& Data)
    {
        // Fire the callback. Data contains more than NewValue, in case it is needed.
        OnManaChange.Broadcast(Data.NewValue);
    }
    
    void MyCharacter::BeginPlay()
    {
        Super::BeginPlay();
        if (AbilitySystemComponent)
        {
            AbilitySystemComponent->GetGameplayAttributeValueChangeDelegate(MyAttributeSet::GetManaAttribute()).AddUObject(this, &MyCharacterBase::OnManaUpdated);
        }
    }
    

    In MyAttributeSet.h

    UCLASS()
    class MYPROJECT_API MyAttributeSet : public UAttributeSet
    {
        // ...
        UPROPERTY(BlueprintReadOnly, Category = "Mana", ReplicatedUsing=OnRep_Mana)
        FGameplayAttributeData Mana;
    
        // Add GetManaAttribute().
        GAMEPLAYATTRIBUTE_PROPERTY_GETTER(URPGAttributeSet, Mana)
    
        // ...
    }
    

    Example for updating the UI via the EventGraph of the character blueprint, which derived from MyCharacter. UpdatedManaInUI is the function which prints the value to the UI.

    Update attribute within blueprint

    Here, UpdatedManaInUI retrieves the value by itself. You might want to use the AttributeValue of OnManaChange.