# Getting Started

{% embed url="<https://youtu.be/R66iJSezpEA>" %}

Project Startup

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

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FW1b7Jlit6ZtkdEV0hRdE%2Fstartupmessagelog.png?alt=media&#x26;token=949f4e00-3558-44e6-93b7-1023250b06bc" alt=""><figcaption></figcaption></figure>

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.&#x20;

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FsfmgqnKGBMh6nQjml7K6%2FGameplayAbilitySystem_Plugin_00.jpg?alt=media&#x26;token=9ef1b143-18a6-406c-9e9a-0d7dd45e7a4c" alt=""><figcaption></figcaption></figure>

* 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.

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2F0TXNesDypJYRXYrTjefJ%2Fthirdpersonsetup.png?alt=media&#x26;token=80e37091-e520-48fd-bf38-859cad0ddfff" alt=""><figcaption></figcaption></figure>

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&#x20;

### 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.

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2Fk38eEVaxnZewgXUofUUv%2Fnewc%2B%2Bclass.png?alt=media&#x26;token=8810983b-dc5b-400e-938e-894d5f73520f" alt=""><figcaption></figcaption></figure>

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FV4HrfrWQHDv62p48u7M7%2Fmyassetmanager.png?alt=media&#x26;token=e7f9bba6-b567-4e53-ae52-36d5e5a60247" alt=""><figcaption></figcaption></figure>

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 GCCModular` GameMode.h or `` `GCCModular` GameModeBase.h`` `

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2F3bPfAKaa0a6meBMjlSCd%2FScreenshot%202023-12-30%20061312.png?alt=media&#x26;token=6b645a7c-036b-4e75-90a8-e476ec005385" alt=""><figcaption><p>Now, we need to configure our Map to use <code>Your Game Mode</code>. Go into your World Settings Panel and select your GameMode in <code>GameMode Override</code>.</p></figcaption></figure>

* 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`.

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2Fw1Q6lbwtul9nTCZseyhx%2Fnetmode2.png?alt=media&#x26;token=c565cf04-9da7-410e-ba3f-c2abb391048b" alt=""><figcaption></figcaption></figure>

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.

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2F6qlvDtG5LSDd6x0WuLrG%2Fdebugpanel2.png?alt=media&#x26;token=f0cd66bf-204e-4c2e-94e4-f77cde0723ea" alt=""><figcaption></figcaption></figure>

## 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:

&#x20;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.&#x20;

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

&#x20;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.&#x20;

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);
	}
```

&#x20;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&#x20;

1\) (started by a bunch of stuff)&#x20;

2\) Check if next init can happen.&#x20;

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)

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FBw2vpcQFPCwNFildCcZZ%2FScreenshot%202023-12-30%20063908.png?alt=media&#x26;token=c659d2ec-cd0b-4769-8fab-9a892404c1c0" alt=""><figcaption></figcaption></figure>

### 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`&#x20;

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

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FxlvARBC6MLVHRxw8jSAB%2FScreenshot%202023-12-30%20070706.png?alt=media&#x26;token=8a4ccf5f-60bb-4908-8597-d09978543d36" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FFyypp5AnS5Toq40bQNqw%2FScreenshot_2023-09-17_071253.png?alt=media&#x26;token=e0a9c213-dba5-4dc2-a4b1-00f3ae0b347e" alt=""><figcaption></figcaption></figure>

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.\ <br>

## 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.

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2Fl9B6doyvX21H5Jnxu8rN%2FpreconfiguredEIS.png?alt=media&#x26;token=374d83d7-9052-4098-8a0b-54cceb23ba81" alt=""><figcaption></figcaption></figure>

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 to`Engine > Input` category inside you `Project Settings`.

* `EnhancedPlayerInputComponent` for the `Default Input Component Class` to `GCCInputComponent`

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FKOgKNEoDKXc4m5H0E9pg%2FScreenshot%202023-12-30%20071751.png?alt=media&#x26;token=45d34397-fb11-49f7-a923-ba99e39df4d1" alt=""><figcaption></figcaption></figure>

Click the `Add` button in the components panel, and add `GCCAbilityInputBinding` to your Character<br>

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FrPwjUvjbBLDWeStQ6ru1%2FScreenshot%202023-12-30%20071937.png?alt=media&#x26;token=3497ecb7-3ab4-4186-9145-5268b0c7ff37" alt=""><figcaption></figcaption></figure>

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

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FRMtnlbR6zflrjjfGEFKK%2FScreenshot%202023-12-30%20071949.png?alt=media&#x26;token=08e4d4df-30b9-4dbf-ad89-fc7880daae7f" alt=""><figcaption></figcaption></figure>

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`

<figure><img src="https://3172028040-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FVR559fdf6Z4L9dTMv7RT%2Fuploads%2FkAgUlHFFm8TxaAZHKE9B%2FIMCDebugPanel.png?alt=media&#x26;token=fbb61733-f699-4c05-9540-9c6f037366bc" alt=""><figcaption></figcaption></figure>
