Нереальный ГАЗ: выводить текущее значение атрибута в интерфейс при его изменении - PullRequest
0 голосов
/ 29 октября 2018

Когда изменяется базовое значение атрибута, доступно UAttributeSet::PostGameplayEffectExecute() для доступа к (новому) значению и GameplayEffect с его контекстом. Я использую это для печати измененного значения в пользовательский интерфейс (это также делается в ActionRPG).

Есть ли что-то подобное для текущего значения атрибута? Как уведомить пользовательский интерфейс, когда FGameplayAttributeData::CurrentValue обновляется?


  • Хотя UAttributeSet::PreAttributeChange() вызывается при каждом обновлении значения, он не предоставляет никакого контекста, поэтому невозможно получить доступ к пользовательскому интерфейсу оттуда (события, передаваемые FAggregator, также не подходят).
  • Вместо этого можно использовать GameplayCue , чтобы установить значение FGameplayAttributeData::CurrentValue в пользовательском интерфейсе (сигнал запускается GameplayEffect , который устанавливает текущее значение). Это возможно путем получения от GameplayCueNotifyActor и использования его событий OnExecute и OnRemove. Однако создание актера только для обновления пользовательского интерфейса, похоже, является пустой тратой ресурсов.
  • Также можно получать информацию с помощью самого пользовательского интерфейса (вызывая функцию, которая обращается к атрибуту каждый тик или с помощью таймера), но по сравнению с управляемым событиями обновлением пользовательского интерфейса это также расточительно.

1 Ответ

0 голосов
/ 09 ноября 2018

Система GameplayAbilitySystem имеет UAbilitySystemComponent::GetGameplayAttributeValueChangeDelegate(), которая возвращает обратный вызов типа FOnGameplayAttributeValueChange, который запускается при изменении атрибута (базовое значение или текущее значение).Это можно использовать для регистрации делегата / обратного вызова, который можно использовать для обновления пользовательского интерфейса.

Минимальный пример

В 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;

    // ...
}

В 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)

    // ...
}

Пример обновления пользовательского интерфейса через EventGraph светокопии персонажа, которая получена из MyCharacter.UpdatedManaInUI - это функция, которая печатает значение в пользовательском интерфейсе.

Update attribute within blueprint

Здесь UpdatedManaInUI получает значение самостоятельно.Вы можете использовать AttributeValue из OnManaChange.

...