ファイアボールと氷の槍に、それぞれMP消費とクールダウンを作った。次は「スタン中は使えない」「装備によって消費MPが変わる」も入れたい。同じ判定をスキルのあちこちへ書いていると、一か所だけ直し忘れることがあります。
Gameplay Ability System(GAS) は、こうしたスキルの共通処理を組み立てるための仕組みです。MPの増減、効果が続く時間、発動を許す条件を、共通の部品で扱えます。
ただし、GASを入れればゲームのルールが自動で完成するわけではありません。この記事では、何を任せられるかを整理し、後半で MPを20消費し、5秒後にまた使える魔法の発動条件 を試します。そのうえで、自分のゲームに導入する価値があるか考えます。
この記事でわかること
- Ability・Effect・Attribute・タグを、誰が管理するか
- MP消費とクールダウンをGameplay Effectで表す仕組み
- 発動できる場合・できない場合を、小さな実験で確かめる方法
- GASを使うか、自作の共通処理で進めるかの判断軸
前半は仕組みの説明です。後半を動かすには、Blueprintの変数とノード操作に加え、C++入門のビルド環境を使います。
GASへ任せること、自分で決めること
スキルには、「火の玉を飛ばす」といった固有の動作と、「必要なMPがあるか調べる」といった共通の処理があります。GASは、その共通部分を扱う土台を提供します。
| GASが用意する仕組み | 作る側が決めること |
|---|---|
| コストを払えるか確かめ、適用する | 何をいくつ消費するか、いつ払うか |
| 効果の有効時間を管理する | 何秒続くか、重なったら延長するか |
| タグに基づいて発動を制限する | スタンや装備を、どのタグで表すか |
| Attributeへの効果 を集計する | ダメージ式、HPの上下限、死亡時の処理 |
| 通信を伴うAbilityの実行を支える | サーバーとクライアントの役割や同期設定 |

対象を選ぶ処理、弾の当たり判定、アニメーション、UIは、ゲームに合わせて組みます。「どこへ当てるか」までGASが決めてくれるわけではありません。
自作でも、関数やComponentへ処理をまとめられます。比較したいのは、個別に書いたスキルとGASだけではなく、自分で共通化した仕組みと、GASの仕組み です。今のゲームに必要な機能と、学習・保守の手間を比べます。
ファイアボールで5つの部品を見る
最初は略称を丸暗記せず、「魔法を使うとき、誰が何をするか」で見てみましょう。

| 部品 | 今回の役割 |
|---|---|
| Ability System Component(ASC) | Actorが持つGASの窓口。使えるAbilityや適用中のEffectを管理する |
| Gameplay Ability(GA) | 「発動したら何をするか」というスキルの処理 |
| Gameplay Effect(GE) | 「MPを20減らす」「5秒間タグを付ける」といった効果の設定 |
| Attribute Set | MPやHPなど、GASで扱う数値を定義する入れ物 |
| Gameplay Tag | 種類や状態を表す、階層のある名札 |
ファイアボールなら、入力からASCへ発動を頼みます。条件を満たすとGAが始まり、コストを確定したところでMP消費と待ち時間のGEが適用されます。GAには、その先の「火の玉を出す」処理を書きます。
ここで Abilityは手順、Effectは効果、Attributeは数値 と分けておくと、名前が増えても見失いにくくなります。今回のMPは、コードや設定欄では Mana という名前で扱います。Gameplay Tagの階層は、タグで敵を分類する記事でも扱っています。
AttributeとEffect:数値はどう変わる?
Attribute は、GASが扱うMPや攻撃力などの数値です。C++では FGameplayAttributeData という型を使い、BaseとCurrentの二つの値 を持ちます。
- Base:効果の計算の基準になる値。最大値という意味ではありません。
- Current:Baseに、現在有効な補正を反映した値。ゲームが現在の強さとして使う値です。
たとえば攻撃力のBaseが10で、5秒間だけ+5するバフをかけると、Currentは15になります。バフが切れればCurrentは10へ戻ります。バフ は能力を高める効果、デバフ は能力を下げる効果のことです。

数値を変えるGEには、次の持続タイプがあります。この表は、周期を付けない一般的な数値の補正を想定しています。
| Duration Policy | どう効くか | 例 |
|---|---|---|
| Instant | 一度実行してBaseを変える | MPを20消費する、HPを30減らす |
| Has Duration | 指定時間だけ補正し、終了時に補正を外す | 5秒間の攻撃力アップ |
| Infinite | 明示的に外すまで補正を続ける | 装備している間の攻撃力アップ |
「5秒後にHPが元へ戻るダメージ」にしたいのか、「5秒間、毒でHPを削り続けたい」のかでも設定が変わります。後者は Period(周期) を使い、一定間隔で効果を実行します。この場合、減ったBaseは毒が切れても戻りません。
Gameplay Effectは、GameplayEffectを親にしたBlueprintとして作り、主にClass Defaultsで設定します。ここでいうEffectは、炎や煙などの見た目のエフェクトではなく、ゲームの数値や状態へ与える効果 です。
MP消費と待ち時間もEffectで表す
Cost(コスト) はスキルを使うための消費、Cooldown(クールダウン) は再び使えるまでの待ち時間です。GASでは、どちらもGEを使って表せます。

今回のCostは「Manaへ-20を加えるInstantのGE」です。Cooldownは「5秒間、Cooldown.Fireballというタグを付けるGE」です。Cooldown用GEには、数値を変える設定がなくても構いません。
AbilityのCostとCooldownの欄へ、それぞれのGEを指定します。GASは発動を試すときに、コストを払えるか、クールダウン中でないかを確認します。
実際の支払いは、Ability内でCommit Abilityを呼んだとき です。Commitはコストとクールダウンを再確認し、通れば両方を適用します。呼び忘れると、発動条件のチェックだけで終わり、MPも待ち時間も変わりません。

Abilityを終える End Ability と、クールダウンの終了も別です。魔法を出す手順をすぐ終えても、5秒のGEは残ります。End Abilityを呼んだからといって、直後にもう一度使えるようにはなりません。
タグで新しい発動を止める
スタンは、一時的に行動を制限する状態です。GASでは、対象のASCに State.Stunned を持たせ、スキル側の Activation Blocked Tags に同じタグを指定すると、その間の発動を禁止できます 。

ただし、これは 新しく発動することを禁止する設定 です。途中まで詠唱しているAbilityを中断するには、キャンセルの処理も必要です。通常の移動や、すでに飛んでいる弾まで自動で止まるわけではありません。
| Abilityのタグ欄 | 何を表すか |
|---|---|
| Asset Tags(旧表記はAbility Tags) | そのAbilityの種類。例:Ability.Fireball |
| Activation Blocked Tags | 発動するActorのASCが持っていると、発動できないタグ |
| Activation Required Tags | 発動するActorのASCが持っていないと、発動できないタグ |
| Activation Owned Tags | Abilityの実行中に、発動するActorのASCへ付くタグ |
タグの辞書へ登録するだけでは、ASCにタグは付きません。今回の実践では、3秒間State.Stunnedを付けるGEを適用します。また、自作のGameplay Tag Container変数へ入れたタグも、それだけではASCのタグにはなりません。
親タグでまとめることもできますが、範囲は具体的に決めましょう。単に State を禁止すると、将来加えた別の状態まで対象になります。まずはState.Stunnedだけで試します。
実践の準備:GASを試す土台を作る
ここからは、ファイアボールの 発動条件 を小さく試します。発動したらPrint Stringで知らせ、MPの変化を見ます。弾や敵へのダメージは、条件が動いてからProjectile Movementの記事などと組み合わせる部分です。
完成すると、Fを押してMPが100→80。すぐ押し直しても80のまま。5秒以上待って押すと60になります。別のキーでスタンを付け、発動が止まることも確かめます。

プロジェクトの準備
- C++入門と同じ、
CppFirstStepというThird PersonのC++プロジェクトを使います。新しく同名で作っても構いません。 - 「Edit → Plugins」で「Gameplay Abilities」を有効にし、エディタを再起動します。
Source/CppFirstStep/CppFirstStep.Build.csのPublicDependencyModuleNames.AddRange(...)で、既存の一覧へ次の3つを追加します。これは、C++からGASの部品を使えるようにする設定です。CoreやEngineなどは残し、項目の間をカンマで区切ってください。
"GameplayAbilities", "GameplayTags", "GameplayTasks"
- 「Tools → New C++ Class」でActorを親にして、
GASPracticeを作ります。生成後はエディタを閉じ、次の2ファイルを差し替えます。
今回は、MPを持つクラスと、それを使う練習用Actorを同じヘッダーに置きます。標準GASでは、このMPの定義に当たるAttribute SetをC++で作ります。その上のAbilityやGEは、Blueprintで設定できます。
GASPractice.h
ヘッダーでは、MPの入れ物と、Blueprintから呼べる3つの操作を定義します。CPPFIRSTSTEP_API はプロジェクト名に由来する印です。別名のプロジェクトなら、生成されたGASPracticeの宣言にあった _API の名前へ合わせてください。
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "AbilitySystemInterface.h"
#include "AbilitySystemComponent.h"
#include "AttributeSet.h"
#include "GASPractice.generated.h"
class UGameplayAbility;
class UGameplayEffect;
// MPをGASの数値として持つ入れ物。
UCLASS()
class CPPFIRSTSTEP_API UPracticeManaSet : public UAttributeSet
{
GENERATED_BODY()
public:
UPROPERTY(BlueprintReadOnly, Category = "Practice")
FGameplayAttributeData Mana;
GAMEPLAYATTRIBUTE_PROPERTY_GETTER(UPracticeManaSet, Mana)
GAMEPLAYATTRIBUTE_VALUE_GETTER(Mana)
GAMEPLAYATTRIBUTE_VALUE_INITTER(Mana)
};
// レベルへ1個置いて、キー入力からGASを試すActor。
UCLASS()
class CPPFIRSTSTEP_API AGASPractice : public AActor, public IAbilitySystemInterface
{
GENERATED_BODY()
public:
AGASPractice();
virtual UAbilitySystemComponent* GetAbilitySystemComponent() const override;
UFUNCTION(BlueprintCallable, Category = "Practice")
void TryUseSpell();
UFUNCTION(BlueprintCallable, Category = "Practice")
void ApplyTestStun();
UFUNCTION(BlueprintCallable, Category = "Practice")
void ShowMana();
protected:
virtual void BeginPlay() override;
UPROPERTY(VisibleAnywhere, Category = "Practice")
TObjectPtr<UAbilitySystemComponent> AbilitySystem;
UPROPERTY()
TObjectPtr<UPracticeManaSet> Attributes;
UPROPERTY(EditDefaultsOnly, Category = "Practice")
TSubclassOf<UGameplayAbility> SpellAbility;
UPROPERTY(EditDefaultsOnly, Category = "Practice")
TSubclassOf<UGameplayEffect> StunEffect;
};
GAMEPLAYATTRIBUTE_... は、MPをGASへ伝える処理や、値の読み取り・初期化を用意するマクロです。ここでは一つずつ仕組みを追うより、ManaをGEから選べるようにする部分 と捉えて進めて構いません。
GASPractice.cpp
実装は、ASCとMPの入れ物を作り、Play時に初期化してAbilityを登録します。Fキーから使うTryUseSpellは、ASCへ発動を頼んだ後、現在のMPを表示します。
#include "GASPractice.h"
#include "Abilities/GameplayAbility.h"
#include "GameplayAbilitySpec.h"
#include "GameplayEffect.h"
#include "Components/SceneComponent.h"
#include "Kismet/KismetSystemLibrary.h"
AGASPractice::AGASPractice()
{
PrimaryActorTick.bCanEverTick = false;
SetRootComponent(CreateDefaultSubobject<USceneComponent>(TEXT("Root")));
AbilitySystem = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystem"));
Attributes = CreateDefaultSubobject<UPracticeManaSet>(TEXT("Attributes"));
}
UAbilitySystemComponent* AGASPractice::GetAbilitySystemComponent() const
{
return AbilitySystem;
}
void AGASPractice::BeginPlay()
{
Super::BeginPlay();
AbilitySystem->InitAbilityActorInfo(this, this);
Attributes->InitMana(100.0f);
if (HasAuthority() && SpellAbility)
{
AbilitySystem->GiveAbility(FGameplayAbilitySpec(SpellAbility, 1, INDEX_NONE, this));
}
else if (!SpellAbility)
{
UE_LOG(LogTemp, Warning, TEXT("GASPractice: Set Spell Ability in Class Defaults."));
}
ShowMana();
}
void AGASPractice::TryUseSpell()
{
if (HasAuthority() && SpellAbility)
{
AbilitySystem->TryActivateAbilityByClass(SpellAbility, false);
}
ShowMana();
}
void AGASPractice::ApplyTestStun()
{
if (!HasAuthority() || !StunEffect)
{
return;
}
FGameplayEffectContextHandle Context = AbilitySystem->MakeEffectContext();
Context.AddSourceObject(this);
AbilitySystem->ApplyGameplayEffectToSelf(
StunEffect.GetDefaultObject(), 1.0f, Context);
UKismetSystemLibrary::PrintString(this, TEXT("Stun: 3 seconds"),
true, true, FLinearColor::Yellow, 5.0f);
}
void AGASPractice::ShowMana()
{
UKismetSystemLibrary::PrintString(this,
FString::Printf(TEXT("Mana: %.0f"), Attributes->GetMana()),
true, true, FLinearColor::Cyan, 5.0f);
}

InitAbilityActorInfo(this, this) の二つの引数は、GASを持つActorと、実際にAbilityを使うActorです。今回はどちらもGASPractice自身です。同じActorに作ったAttribute Setは、ASCから見つけられます。
GiveAbility は「このActorが使えるスキル」として登録する処理です。登録しただけでは発動せず、TryActivateAbilityByClassで発動を頼みます。
エディタを閉じた状態で、Visual Studioの「Development Editor / Win64」でプロジェクトをビルドします。成功したらエディタを開き直してください。ここまでのC++は練習の土台で、次から効果とスキルの設定を作ります。
実践:MP20消費・5秒待ちを試す
1. タグと3つのEffectを用意する
「Edit → Project Settings → GameplayTags」から、Cooldown.Fireball と State.Stunned を登録します。登録操作はGameplay Tagの記事と同じです。
コンテンツブラウザで「Blueprint Class → All Classes」からGameplayEffectを選び、次の3アセットを作ります。各アセットを開き、Class Defaultsを設定します。
| アセット | Duration Policy | 設定 |
|---|---|---|
| GE_Cost_Fireball | Instant | Modifiersへ1項目。Attribute=PracticeManaSet.Mana、Modifier Op=Add、MagnitudeのScalable Float=-20 |
| GE_Cooldown_Fireball | Has Duration | Duration MagnitudeのScalable Float=5.0。Cooldown.Fireballを付与 |
| GE_Stun_Practice | Has Duration | Duration MagnitudeのScalable Float=3.0。State.Stunnedを付与 |
Modifier は数値をどう変えるか、Magnitude はその量です。今回は計算式や表を使わず、Scalable Float欄に固定値を入れます。Periodは0のままです。

タグを付ける2つのGEでは、「Components」に Grant Tags to Target Actor を追加し、「Add Tags」の追加欄へタグを指定します。これは「効果が続く間、対象のASCへタグを付ける」部品です。「Asset Tags」はGE自身の分類なので、代わりにはなりません。
古いUE5.2以前の解説ではGranted Tagsへ直接設定する画面が出てきます。この記事は、Componentsを使うUE5.3以降の画面を前提にしています。
2. AbilityへCostとCooldownを割り当てる
GameplayAbilityを親にしたBlueprintを作り、GA_Fireball と名付けます。Class Defaultsを次のように設定します。
| 設定 | 値 |
|---|---|
| Cost Gameplay Effect Class | GE_Cost_Fireball |
| Cooldown Gameplay Effect Class | GE_Cooldown_Fireball |
| Activation Blocked Tags | State.Stunned |
| Instancing Policy | Instanced Per Actor |
| Net Execution Policy | Server Only |
Instanced Per Actorは、使うActorごとにAbilityの実体を一つ持つ設定です。この練習では、それを発動のたびに使います。Server Onlyは、今回の実験をゲームの処理を決める側で動かす設定で、後述の1人用Playで試します。

今回はクラス名でAbilityを指定するため、Ability自身のAsset Tagsは空で構いません。Cooldown.Fireballは、CooldownのGEが対象へ付けるタグです。
3. Commitの成功時だけ、発動を表示する
GA_FireballのEvent GraphでEvent ActivateAbilityを追加し、白い実行線をCommit Abilityへつなぎます。Commitの実行出力はBranchへ、赤いReturn ValueはBranchのConditionへつなぎます。CommitのTargetはSelfです。

BranchのTrue側をPrint Stringへつなぎ、In Stringを Fireball!、Durationを5.0にします。詳細ピンを開き、Print to ScreenとPrint to Logをオンにします。その後にEnd Abilityを呼びます。False側は、何も表示せずEnd Abilityへつなぎます。End AbilityもTargetはSelfです。

図のA・BはTrueとFalseの実行線の続きです。同じEvent Graphでつなぎ、AやBというノードを作る必要はありません。
Return ValueはCommitの結果です。boolはTrue(成功)かFalse(失敗)の二択を表します。Commit Abilityは、成功と失敗の実行出力を持つノードではありません。boolの結果をBranchへ渡して分ける 点を、図と合わせて確認してください。
End Abilityは両方の経路へ置きます。今回のInstanced Per ActorでAbilityが動いたままだと、次の発動を受け付けない原因になります。
4. 練習用Actorを配置し、キーから呼ぶ
C++ ClassesのGASPracticeから子Blueprint BP_GASPractice を作り、Class Defaultsの「Practice」で次を選びます。
| 項目 | 値 |
|---|---|
| Spell Ability | GA_Fireball |
| Stun Effect | GE_Stun_Practice |
BP_GASPracticeをレベルへ 一つだけ 置きます。見た目のないActorですが、Outlinerで選べれば十分です。BeginPlayでのAbility登録とMP初期化はC++側にあるので、BPへ同じ処理を追加する必要はありません。
Outlinerで配置した個体を選び、「Blueprints → Open Level Blueprint」を開きます。右クリックからその個体への参照を作り、次の入力を組みます。関数は参照の出力からドラッグして検索できます。
- FのPressed → Try Use Spell
- GのPressed → Apply Test Stun
- MのPressed → Show Mana
各呼び出しのTargetには、同じBP_GASPracticeの参照をつなぎます。Releasedは使いません。

GとMも、同じ配置ActorをTargetにしてつなぎます。

5. MPと待ち時間を確かめる
Compileして保存し、Playの設定を「Number of Players=1」「Net Mode=Play Standalone」にします。Play後、ゲーム画面をクリックして入力を受け付ける状態にしてください。
| 操作 | 期待する表示 |
|---|---|
| Playを始める | Mana: 100 |
| Fを一度押す | Fireball! と Mana: 80 |
| 5秒以内にもう一度F | 新しいFireball!は出ず、Mana: 80 |
| 前回の発動から5秒以上待ってF | Fireball! と Mana: 60 |
| 5秒以上ずつ待ち、計5回発動する | Mana: 0 |
| さらに5秒以上待ってF | 新しいFireball!は出ず、Mana: 0 |
画面に前のFireball!が残っている場合は、新しい行が増えたかを見ます。Output Logでも読めます。MPの変化と成功時の表示を組み合わせて判断してください。
6. スタンで発動を止める
StopしてPlayし直し、MP100の状態へ戻します。最初にGを一度押し、すぐFを押します。スタン中はFireball!が出ず、Manaは100のままです。Gを押してから3秒以上待ってFを押すと、Mana80になり発動します。

スタンの実験を別のPlayで始めるのは、クールダウンやMP不足と原因を混ぜないためです。ここでは移動を止める処理を作っていないので、Third Personのキャラクターが歩けることとは矛盾しません。
| 想定どおりにならない場合 | 確認する場所 |
|---|---|
| Mana: 100が最初に出ない | BP_GASPracticeの配置、ビルド、Play中のログ |
| Fを押してもManaすら出ない | Level BPのPressedとTarget、ゲーム画面へのフォーカス |
| Manaは出るがFireball!が一度も出ない | Spell Ability、GiveAbility、GAのCost・タグ設定 |
| Fireball!は出るがMPが減らない | Costの割り当て、ManaのModifier、Commitの接続 |
| 連打でMPが減る | Cooldown GEの割り当て、5秒のDuration、付与タグの設定 |
| 一度だけ使えて、その後ずっと使えない | True/False両経路のEnd Ability、MP残量 |
| Gの後でも発動できる | Stun Effect、Grant Tags to Target Actor、GAのActivation Blocked Tags |
数値だけ変えて比較する
Stopし、Costの-20を-35へ変更します。Playし直し、5秒以上ずつ待ってFを押すと、MPは100→65→30。次は35を払えず30 のままになります。GAのグラフに「MPが35以上か」という条件を足していません。
次に元の-20へ戻し、Cooldownの5秒を2秒に変えて試します。効果の設定と、発動時の処理を別々に変えられること が、GASの使い心地を判断する材料になります。
導入はスキルの個数だけで決めない
同じ実験は、MP変数とTimerを使って自作もできます。GASの価値は、この一つの魔法を作れることより、効果や条件を共通の仕組みで扱い続けられることにあります。
| 今の状況 | 判断の方向 |
|---|---|
| 数個のスキルが独立して動き、条件も単純 | 自作の関数やComponentでまとめる方法から試す |
| コスト・待ち時間・状態異常を、多くの能力で共有する | GASの小さな試作を作り、設定と保守のしやすさを比べる |
| 効果の重複や通信を含む能力設計が中心になる | GASを有力な候補として、必要な機能を早めに検証する |
| すでに自作で安定している | 移行で得られるものと、作り直す範囲を比べる |

スキルが多いから必須、少ないから不要とは言い切れません。少数でも効果の組み合わせが複雑なゲームはありますし、多数でも単純なデータ差だけで済むゲームはあります。
迷う場合は、本番とは別の小さなプロジェクトで、代表的な能力を一つか二つ作ってみてください。MP消費、状態による制限、重複する効果など、自分のゲームで難しい部分を含めます。「2本目は何を変更したか」「動かないときに原因を追えたか」を比べると、導入後の作業を想像できます。
あとから導入することもできますが、HPや能力、セーブ、UIの接続まで変える場合は移行作業が増えます。大きくなる前に試作しておくと、判断のために本編を作り直す事態を減らせます。
おまけ:先に知っておくと良いこと
HPの上下限や死亡処理は自分で作る
GASは、Healthという名前だけで0〜最大HPへ収めてくれません。HPが0になったら倒れる処理もゲーム側で作ります。今回のManaは、初期値100と支払えるCostだけに用途を絞っています。
本格的に広げるときは、Attribute SetのPreAttributeChangeやPostGameplayEffectExecuteなどを使い、どの値にどの制限をかけるか決めます。効果による数値の増減はGEへまとめると追いやすくなりますが、直接の値変更が一律に禁止されているわけではありません。
Actorを消した後も残すものを考える
今回のASCは練習用Actorが持つので、そのActorと一緒に終わります。キャラクターが死んで作り直されても能力や状態を残したいなら、PlayerStateなどへASCを持たせる設計もあります。
ASCの持ち主と、実際に能力を使うAvatarを分けると、再生成 したキャラクターとの結び直しも必要です。まずはGame Frameworkの役割と合わせて、何を残したいか決めます。
通信や演出へ広げる
今回のコードは1人用の練習です。通信へ広げるには、AttributeのReplicationやActor Infoの初期化タイミングなどを設計します。Replicationは、サーバー側の状態をクライアントへ伝える仕組みです。GASの設定を一つ変えるだけで全ての同期が完成するわけではありません。
見た目には Gameplay Cue を使えます。能力や効果に応じて、音やパーティクルなどの演出を呼ぶ仕組みです。また、Ability Task はアニメーションの終了やイベントを待ちながら、Abilityの処理を進めるときに役立ちます。
公式サンプルのLyraは実例を読む教材になります。土台以外の設計も多いため、まずは今回のCost・Cooldown・Tagがどこに対応するか探すと、読み始める場所を決めやすくなります。
まとめ
- Abilityが「やること」、Effectが「起きる変化」、Attributeが「数値」、タグが「今の状態」
- MP消費とクールダウンは、どちらもGameplay Effectで表せる
- 発動できない理由は、コスト・クールダウン・タグのどれかに分かれる
- スキルの数だけでは、導入するかは決まらない
判断するときの問いかけは、「効果の付け外しが、あとから増えそうか」 です。増えるならGAS、決め打ちで足りるなら自作の共通処理で十分です。
状態をタグで扱う話は Gameplay Tags、素朴なダメージ処理は ダメージを与える にあります。
参考:Gameplay Ability System、Gameplay Abilities、Gameplay Effects、Commit Ability。