Shaun Reed
UE5 gameplay ability system
Links and sources
Source code example of using the GAS: GASShooter GitHub project
Unofficial but detailed GAS Documentation
Epic livestream in depth look at GAS
Setting up GAS youtube tutorial
Brief
In the sections below, my game is named unrealgame5
, and any appearances of this string should be replaced by your own project name. This page outlines the process of setting up the Gameplay Ability System for use in an Unreal Engine 5 game using C++. Blueprints can still be used for prototyping new abilities, which can later be translated to C++.
Project Plugins and Modules
To setup out UE5 project to use the required modules, we need to edit our <PROJECT_NAME>.build.cs
file. This file should have been generated by Unreal Engine when your project was created, and for me my file is named unrealgame5.build.cs
Initial contents of unrealgame5.build.cs
, before I made any changes.
1 | using UnrealBuildTool; |
Add "GameplayAbilities", "GameplayTags", "GameplayTasks"
modules to unrealgame5.build.cs
so your file looks like the following.
1 | using UnrealBuildTool; |
Then within the editor go to Edit->Plugins...
and enable the Gameplay Abilities
plugin. You will need to restart the editor for the changes to apply.
C++ Initial Setup
To set up the scaffolding for the GAS, we need a few things -
- Enumeration of abilities to correlate with input actions
- Core GameplayAbilitySystem
- Set of attributes for our player and / or enemies
- Player character inheriting from
IAbilitySystemInterface
class - GameplayEffect to apply default attributes for our player / enemies
- AnimGraphs with Montage slots for handling abilitiy animations
So, to complete this setup you will at least need to define a few new classes for your project.
For my project I follow the same naming convention used with GASDocumentation. I’ll paste it below, but for the first few files required to set up the Gameplay Ability System (GAS), we are defining the backend of the system so none of these conventions apply. For these files, I added the GAS_
convention.
1 | Prefix Asset Type |
Ability Enumeration
First, we need to modify the contents of the header file for our unreal project. My project is named unrealgame5
so the file is unrealgame5.h
, and the contents are below. If you already have information here, just make sure the EGASAbilityInputID
enumeration is added to the header file and save your changes. This enumeration is used to correlate input actions to activate certain abilities in our game.
Note: Attack
below must either be changed to match or made to match some keybind within your Edit->Project Settings->Input
options menu.
1 | // Copyright Epic Games, Inc. All Rights Reserved. |
Ability System Component
Next, we need to create an AbilitySystemComponent
. This will be the component that we attach to actors that we want to take use with the GAS. To create this component, open your project in unreal and create a new C++ source file, inheiriting from the AbilitySystemComponent
base class.
This base class is provided by UE5, assuming you have the GameplayAbilities
plugin installed to your project. In order to inherit from it, we need to create a new C++ Class. We must be in the C++ Classes
subdirectory of our project in order to do this.
Next click All Classes
and search for AbilitySystemComponent
.
Click next and name your class, I’ll name this class GAS_AbilitySystemComponent
.
The generated files are seen below. You don’t need to put anything else in here for now. Note that UE5 prefixed our original class name GAS_AbilitySystemComponent
with a U
- it’s name in the source code is UGAS_AbilitySystemComponent
, this is normal and to be expected.
1 | // GAS_AbilitySystemComponent.h |
1 | // GAS_AbilitySystemComponent.cpp |
Gameplay Abilities
Next we’ll setup the base class that we will use for adding abilities to our game. To do this we need to create another new C++ Source file like we did in the previous step, only this time we will inherit from the GameplayAbility
class provided with the GameplayAbilities
UE5 plugin.
I named this class GAS_GameplayAbility
and the source code is seen below
1 | // GAS_GameplayAbility.h |
1 | // All content (c) Shaun Reed 2021, all rights reserved |
Attribute Sets
Next, we need to create an AttributeSet
for our game. Repeat the process of creating a new C++ sourcce file for your ue5 project, but this time inherit from AttributeSet
I named this class GAS_AttributeSet
and the files genereated are below
1 | // GAS_AttributeSet.h |
1 | // GAS_AttributeSet.cpp |
Character Setup
In the files below, my character is named ThirdPersonCharacter
, so any appearances of this string may need to be replaced with your character’s name instead. To setup your character that inherits from ACharacter
base class, make the following changes to your files.
In the ThirdPersonCharacter.h
file, make sure you’re inheriting from public IABilitySystemInterface
. The start of your class should look like this. Pay attention to the includes.
1 | // All content (c) Shaun Reed 2021, all rights reserved |
Character Components
To initialize the core GameplayAbilitySystem components on our character, we add an instance of our GAS_AbilitySystem
class using the UGAS_AbilitySystemComponent
typename, and we also add an instance of our GAS_AttributeSet
class using the UGAS_AttributeSet
type.
1 | UCLASS() |
Now we need to modify the character’s constructor to add the new components we’ve declared. I removed the code from my constructor that wasn’t related to the GAS. The additions are below.
1 | // ThirdPersonCharacter.cpp |
So we have the core components we need, and the next step is to provide the required definitions for virtual functions we’ve inheirted from IAbilitySystemInterface
Virtual Functions
We need to overload a virtual function InitializeAttributes()
to handle initializing the attributes for our game at the start. We also declare the DefaultAttributeEffect
member variable to help define and apply the default attributes for our character.
Similar to how we defined default attributes, we define default abilities for our character by overloading the GiveAbilities()
function. We also add the DefaultAbilities
array to store the default abilities for the character.
Notice that we use the UPROPERTY
macro to apply EditDefaultsOnly
to our components. This will later allow us to modify these components in the UE5 editor for our character’s blueprint, so we can dynamically add and remove attributes and abilities for our player without modifying the code each time.
For the next step, we need to override PossessedBy
and OnRep_PlayerState()
to define how to update the server and client of the player state respectively.
1 | // ThirdPersonCharacter.h |
And see the definitions for these functions below
1 | // ThirdPersonCharacter.cpp |
And just to be sure we have all the headers we need, here are the final includes for my character
Defining Abilities
At this point we have configured GAS for our project and our character, so we’re ready to start defining our abilities!
In my assets folder, I just created an Abilities
subdirectory and continued with the steps below, creating the assets within this directory.
Creating the Attack Ability
First, open the animation blueprint for your character and add a montage Slot 'DefaultSlot'
to your anim graph. For me, the screen looks like the below after the changes have been made. Make sure to save and apply these changes.
Make a new blueprint deriving from the GAS_GameplayAbilitiy
class that we defined earlier.
I named this GA_Attack
and opened it for editing.
Make sure the Ability Input ID
matches the input action we want the ability to be mapped to. This is found under the details
panel.
Next, open GA_Attack
for editing and add the following blueprint nodes. Add the GetActorInfo
node in the context menu in the screenshot, be sure to uncheck ‘Context Sensitive’ if it isn’t appearing at first.
Now right click the GetActorInfo
node and select Split Struct Pin
to split the actor into its components
And connect the skeletal mesh pins to finish the blueprint for GA_Attack
Under the Montage To Play
pin on the Play Montage
node, you may not have a montage available for your skeleton.
If you also don’t have an animation, check out Mixamo for a free anmation and see the page on Retargeting Skeleton Animations
Then create a montage by watching this quick youtube video. If you’re doing a simple punch animation, you probably just need to create a montage and click and drag the animation into the center of the screen and save. It’s pretty simple, but you can use Motages to do some pretty neat things. Maybe for the first montage try making a one-off animation that doesn’t loop like punching or a grab motion for interactions.
Once you have the montage made, select it here in this node, and then play the game. You’ll now be able to see your character performing the attack!
Default Abilities and Attributes
First I created a new Blueprint Class using the editor and derived from the GameplayEffect
class. Applying this effect will result in the player or character being granted a set of default abilities.
I named this GE_CharacterDefaults
, and opened it for editing. The screenshot below contains all settings I modified under the Class Defaults
panel. If it isn’t in this screenshot, I didn’t change it.
Then I opened my BP_ThirdPersonCharacter
blueprint for editing and applied the following settings within the details
panel. You should notice at this point that the DefaultAttributeEffect
and DefaultAttributes
in this screenshot are actually the components we exposed to the editor in our ThirdPersonCharacter.h
file earlier with UPROPERTY
and EditDefaultsOnly
.
Damage Effect
To prove the system is working, create a new blueprint that derives from GameplayEffect
and apply the settings below
Then, in the event chart for your BP_ThirdPersonCharacter
add a BeginPlay
node and apply the damage when the game starts.
Hit play and then open a console and type showdebug abilitysystem
to see that your HP should now be 80
on the lefthand side. Remove the damage to your player when youre done testing, but you can keep the GE_Damage
asset around to use it later.
Creating Additional Abilities
At a higher level, the steps for adding a new ability are below
- Add the input action to the enum defined in
unrealgame5.h
(AKA<YOUR_PROJECT_NAME>.h
) - Recompile in the editor or within the IDE of your choice
- Restart the editor
- Create a blueprint deriving from GAS_GameplayAbility
- Define the
ActivateAbilitiy
event for this new blueprint, and assign anAbility Input ID
within theDetails
panel - Create a new Animation Montage for the ability, if needed (and assign to play on
ActivateAbility
event) - Grant the abilitiy under the
Details
tab in theDefault Abilities
section while editing theBP_ThirdPersonCharacter
blueprint - Add the input action to your project under
Edit->Input
if it doesn’t already exist
Debugging
To see useful information on the GAS, enter play mode and hit the tilde (~) key to open a console. Then, type showdebug abilitysystem
, and youll notice you can see your character stats even if there’s no UI elements to represent them yet.