Getting Started

Project Startup

When you first open your project with GCC enabled, you will see the following message in your message log

Dont panic! This is not an error, this is a validation check from the Game Features plugin comes by default when you enabled the plugin and since GCC use this plugin for our GameFeatureAction.

Upon clicking the link Add entry to PrimaryAssetsTypesToScan?, you should be prompt with a message to restart the editor.Once your editor is restarted,DefaultGame.ini file will be updated accordingly and those validation errors won't appear anymore.

Prerequisites

  • Enable the Gameplay Ability System Plugin in the Edit -> Plugins window.

  • To get the full range of capabilities of this system, add "GameplayAbilities", "GameplayTags", a2nd "GameplayTasks" to PublicDependencyModuleNames in your project's "(ProjectName).Build.cs" file.

To use the Gameplay Ability System, add the three module names anywhere in the braced list, as follows:

PublicDependencyModuleNames.AddRange(new string[] { "GameplayAbilities", "GameplayTags", "GameplayTasks" });

Setting with fresh project

In this setup, we will be using the Third Person BP template for our initial project setup.

Create that project by launching the Unreal Engine instance and choose Third Person Project with Blueprint as the project default.

Set your project location and name your project and create the project.

AbilitySystemGlobals

If you want to subclass classes like UGameplayCueManager or FGameplayAbilityActorInfo, you require to subclass UAbilitySystemGlobals to use those custom subclasses. By default, GCC use ASG to setup FGCCGameplayAbilityActorInfo and FGCCAttributeSetInitter

You need to go to your project Config->DefaultGame.ini under [/Script/GameplayAbilities.AbilitySystemGlobals]

[/Script/GameplayAbilities.AbilitySystemGlobals] AbilitySystemGlobalsClassName=/Script/GCC.GCCAbilitySystemGlobals GlobalGameplayCueManagerClass=/Script/YourGame.YourGameplayCueManager PredictTargetGameplayEffects=false bUseDebugTargetFromHud=true ActivateFailIsDeadName=Ability.ActivateFail.IsDead ActivateFailCooldownName=Ability.ActivateFail.Cooldown ActivateFailCostName=Ability.ActivateFail.Cost ActivateFailTagsBlockedName=Ability.ActivateFail.TagsBlocked ActivateFailTagsMissingName=Ability.ActivateFail.TagsMissing ActivateFailNetworkingName=Ability.ActivateFail.Networking

ActivateFails config need to use what our native tag we define inside GCC GCCGameplayTags Used to define Global Activation Fail Tag Define in DefaultGame.ini

AssetManager Setup

#Note In 5.3, the setup below is no longer necessary as the call UAbilitySystemGlobals::Get().InitGlobalData() is being call by default inside GameplayAbilityModule

Go to Tools->New c++ class and find UAssetManager and create your assetmanager.

Open your IDE and add this code in your header and cpp file.

Header:

public:

    static UMyAssetManager& Get();

    /** Starts initial load, gets called from InitializeObjectReferences */
    virtual void StartInitialLoading() override;

CPP:

#include "AbilitySystemGlobals.h"


UMyAssetManager& UMyAssetManager::Get() 
{
    UMyAssetManager* Singleton = Cast<UMyAssetManager>(GEngine->AssetManager);

    if (Singleton)
    {
        return *Singleton;
    }
    else
    {
        UE_LOG(LogTemp, Fatal, TEXT("Invalid AssetManager in DefaultEngine.ini, must be MyAssetManager!"));
        return *NewObject<UMyAssetManager>();    // never calls this
    }
}


void UMyAssetManager::StartInitialLoading() 
{
    Super::StartInitialLoading();
    UAbilitySystemGlobals::Get().InitGlobalData();
}

Starting in UE 4.24, it is now necessary to call UAbilitySystemGlobals::Get().InitGlobalData() to use TargetData, otherwise you will get errors related to ScriptStructCache and clients will be disconnected from the server. This function only needs to be called once in a project. Fortnite calls it from UAssetManager::StartInitialLoading() so thats why we do the same.

  • Next, go to your Config/DefaultEngine.ini and add this into your [/Script/Engine.Engine]

[/Script/Engine.Engine]
AssetManagerClassName=/Script/MyProject.MyAssetManager
  • Find the ThirdPerson folder and find your GameMode class. Reparent your game mode class to GCCModularGameMode.h or ``GCCModularGameModeBase.h``

  • Find the ThirdPerson folder and find your Character class. Reparent your character class to GCCModularCharacter.h

  • Right click, go to blueprint and create a PlayerState class. Reparent your player state class to GCCModularPlayerState.h

  • Right click, go to blueprint and create a PlayerController class. Reparent your player controller class to GCCModularPlayerController.h

  • Go to Project Settings -> Maps and Modes -> Default Game Instance Class and set GCCGameInstance or its child as the default game instance

Once you finish, find the three dot near Play button, find NetMode and choose Play As Client.

Then, press Play. If we setup everything correctly, we should get no error. To confirm that, enter this command into the console command showdebug abilitysystem and you will be greeted with this debug panel.

Initialization

The PawnExtComponent extends the game frameworks init. A large part of the PawnExtComponent is boilerplate to kick that init off, for the most part you don't want to modify that.

There are 4 major phases to this:

1) Kick of the init framework. You'll see this done in a LOT of places and it is basically boilerplate. Ultimately this involves calling CheckDefaultInitialization on every component that needs to be part of this framework.

Anywhere you see that called, consider to be boilerplate for the GameFrameworkInit.

I should note: Although the PawnExtComponent "coordinates" a lot of this, all these steps really need to be on each of the components using the init. So you'll see CheckDefaultInitailization called and overriden in both the pawn ext comp and the hero comp.

2) CanChangeInitState. This is where the component searches the actor to make sure enough data has been replicated to proceed to the next step of init.

3) HandleChangeInitState. This is where the init is actually performed for components that are using the init framework.

Generally this is just caching references to other components or to do any special init.

4) Do the init on the components that haven't been added to the init framework. For the most part the PawnExtComp owns ASC init. This is because they didn't add those components to the init framework.

The Hero Component is the place where in HandleChangeInitState::CurrentState == GCCGameplayTags::InitState_DataAvailable && DesiredState == GCCGameplayTags::InitState_DataInitialized initialize AbilitySystemComponent with PlayerState as its OwnerActor

	if (UGCCPawnExtensionComponent* PawnExtComp = UGCCPawnExtensionComponent::FindPawnExtensionComponent(Pawn))
	{
		// The player state holds the persistent data for this player (state that persists across deaths and multiple pawns).
		// The ability system component and attribute sets live on the player state.
		PawnExtComp->InitializeAbilitySystem(GCCPS->GetGCCAbilitySystemComponent(), GCCPS);
	}

Steps 2 and 3 are the "meat" of the init

What is InitState?

  1. Spawned is as it sounds

  2. Data Available is where the ASC gets hooked up

  3. Data Initialized is where all the init that relies on the ASC happens

  4. Ready is an end state that doesn't do much.

So the step order is

1) (started by a bunch of stuff)

2) Check if next init can happen.

3) Do the next init, forward the init to step 4 (if relevant), then loop back to 1 for the next framework "state" (Spawned, Data Available, Data Init, Ready) (edited)

If step 2 fails, then the actor collectively waits until step 1 is fired off again by one of the components hitting one of the many CheckDefaultInitialization conditions.

AbilitySystemComponent

As of GCC v2.6, GCC is configured to be use with ASC on the PlayerState as its OwnerActor. This is due to how GCCPawnExtensionComponent being setup to handle PlayerState as its OwnerActor to initialize AbilitySystemComponent. In the future, this will be change with the introduction of ``IGCCPawnAbilitySystemInterface`` to implement on AvatarActor to determine a way for the PawnExtComponent to generically determine what kind of pawn it is operating on.

By default, AbilitySystemComponent live inside PlayerState and have a few properties you can configure.

  1. Granting abilities by default (and if that ability have OnSpawn ActivationPolicy, it will activate)

  2. Granting gameplay effects by default

  3. Granting attribute set with its initialization value using data table

  4. Granting ability sets by default ( As of GCC v2.6, this is not implemented yet)

  5. Attribute Set Initialization Method where how attribute set will be initialize its values by using GameplayEffect, Ability Set or AttributeSetInitter ( As of GCC v2.6, this is not implemented yet)

Attribute Set Initialization

By default, AbilitySystemComponent provides a field called Default Attributes to initialize Gameplay Attributes through data table. You need to specify the attribute set you want use and specify the data table based on AttributesMetaData

Inside your character blueprint, you can see a field under GCC->Character->AttributeSets and this is to add additional attribute set. In the future, this will be move to AbilitySystemComponent.

Next, attribute set can be initialize using attribute set initter. Make sure to setup abilitysystemglobals inside your DefaultGame.ini. Next, you need to call UGCCAbilitySystemGlobals::GetASG().InitAttributeSetDefaults(GetterForYourASC(),InitializationKey, 1,true) when your ASC is initialize. In my case, i call it inside my PawnExtensionComponent after i call InitializeWithAbilitySystem

  1. Import your .csv to be use for your values

  2. Specify the path inside [/Script/GameplayAbilities.AbilitySystemGlobals] and under this

    +GlobalAttributeSetDefaultsTableNames=/Game/PathToYourCSV/AttributeTable.AttributeTable

  3. Make sure your attribute is YourAttributeSet.YourAttribute inside your table or the initter cant find the attribute and initialize the value

Open up the gameplay debugger for GAS with showdebug abilitysystem, we should see values for each Gameplay Attribute we configured in the Data Table updated accordingly.

InputBinding with Enhanced Input System

From Unreal Engine 5.1 onwards, the EnhancedInput plugin will replace the legacy input system. If your project is from Unreal Engine 5.0 and below, make sure to enable the EnhancedInput Plugin by:

Plugins->Input->EnhancedInput

By default, the Third Person template preconfigured to use EnhancedInputSystem and there's some setup configured.

We can just use the preconfigured Binding system on BeginPlay or using GCCAbilityInputBinding component.In this setup, we want to use the component as it comes with some convenience functions for input binding.

Navigate toEngine > Input category inside you Project Settings.

  • EnhancedPlayerInputComponent for the Default Input Component Class to GCCInputComponent

Click the Add button in the components panel, and add GCCAbilityInputBinding to your Character

In the details panel, you can configure you Input Mapping Context and Input Priority

We can delete the BeginPlay setup and use the component to bind our input mapping context. The Third Person template also comes with preconfigured InputActions and InputMappingContext in ThirdPerson/Input folder.

To see if you configure Enhanced Input correctly, go to the command bar and use the following command:

showdebug enhancedinput

Last updated