GameplayAbilities API – Implementing stats with UAttributeSet

2021/01 02 14:01

The GameplayAbilities API allows you to associate a set of attributes, that is, UAttributeSet, to an Actor. UAttributeSet describes properties appropriate for that Actor’s in-game attributes, such as Hp, Mana, Speed, Armor, AttackDamage, and so on. You can either define a single game-wide set of attributes common to all Actors, or several different sets of attributes appropriate for the different classes of actors.

Getting ready

AbilitySystemComponent is the first thing you will need to add to your actors to equip them to use the GameplayAbilities API and UAttributeSet classes. To define your custom UAttributeSet, you will simply derive from the UAttributeSet base class and extend the base class with your own series of UPROPERTY members. After that, you must register your custom AttributeSet with your Actor class’s AbilitySystemComponent.

How to do it…

  1. If you have not done so already, complete Steps 1-4 of the GameplayAbilities API – triggering an actor’s gameplay abilities with game controls recipe to link to the GameplayAbilities API in your ProjectName.Build.cs file and enable its functionality.
  2. Create a new C++ class  by going to the Content Browser and selecting Add New | Add C++ Class. From the Add C++ Class menu, check the Show All Classes option. From there, type in attr and select AttributeSet as your parent class. From there, click the Next button:
  1. Give the class a Name of GameUnitAttributeSet and click on Create Class:

Once created, deck the class out with a set of UPROPERTY specifiers that you want each Actor to have in their property set.

  1. For example, you might want to declare your UAttributeSet derivate class similar to what’s given in the following piece of code:
#pragma once

#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "GameUnitAttributeSet.generated.h"

/**
*
*/
UCLASS(Blueprintable, BlueprintType)
class CHAPTER_11_API UGameUnitAttributeSet : public UAttributeSet
{
GENERATED_BODY()

public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = GameUnitAttributes)
float Hp;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = GameUnitAttributes)
float Mana;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = GameUnitAttributes)
float Speed;
};

If your code is networked, you might want to enable replication on each of the UPROPERTY specifiers with the replicated declaration in the UPROPERTY macro.

  1. Connect GameUnitAttributeSet with your AbilitySystemComponent inside your Actor class. We can do this with the Warrior class we created previously by opening the Warrior.h file and adding the following function declaration:
virtual void PostInitializeComponents() override;
  1. Then, open Warrior.cpp and add the following #include:
#include "GameUnitAttributeSet.h"
  1. Afterwards, implement that function:
void AWarrior::PostInitializeComponents()
{
Super::PostInitializeComponents();

if(AbilitySystemComponent)
{
AbilitySystemComponent->InitStats(UGameUnitAttributeSet::StaticClass(), NULL);
}
}

You can put this call somewhere in PostInitializeComponents(), or in code that is called later than that.

  1. Once you have registered UAttributeSet, you can move on with the next recipe and apply GameplayEffect to some of the elements in the attribute set.
  2. Be sure your Actor class object implements IAbilitySystemInterface by deriving from it. This is extremely important as the UAbilitySet object will attempt a cast to IAbilitySystemInterface to call GetAbilitySystemComponent() on it at various places in the code.

How it works…

UAttributeSets simply allow you to enumerate and define attributes of different actors. GameplayEffects will be your means to make changes to the attributes of a specific actor.

There’s more…

You can code in definitions of GameplayEffects, which will be things that act on the AbilitySystemComponent’s AttributeSet collections. You can also write GameplayTasks for generic functions that run at specific times or follow particular events, or even in response to a tag addition (GameplayTagResponseTable.cpp). You can define GameplayTags to modify GameplayAbility behavior, as well as select and match gameplay units during play.