UE4 BPプロジェクトに Gameplay Ability System を導入する方法

#はじめに
C++プロジェクトに、[**Gameplay Ability System**](https://docs.unrealengine.com/ja/InteractiveExperiences/GameplayAbilitySystem/index.html) (以下GASと略します) を導入する方法は、
[**おかわりはくまいさんのブログ**を参照](https://okawari-hakumai.hatenablog.com/entry/2018/07/22/165242)するのが、ベストな選択肢だと思います。
 
ブループリントで作成したプロジェクトに、
GASを導入したくなった時用の方法を、残しておこうと思います。（備忘録）

また、筆者はプログラミングの素人です。間違いを見つけたら、ご指摘ください。

#プラグイン Gameplay Abilities とは
[**詳しくは公式のドキュメント**](https://docs.unrealengine.com/ja/InteractiveExperiences/GameplayAbilitySystem/index.html)を確認していただければと思いますが、
自分の認識としては、**「オンラインゲームを作る上で、特に重要なシステムらしい」**という認識です。
実際に使っているプロのプログラマの方の講演で、
なぜGASを使うのかという内容の動画が、とても分かりやすいと思いました。
>[**Using the Gameplay Ability System | Unreal Fest Europe 2019 | Unreal Engine**](https://youtu.be/_713CSOWkTU)

[（字幕読むのがしんどい方には、「CaptionSpeaker」をお勧めします。chrome extension）](https://chrome.google.com/webstore/detail/captionspeaker/infafaffjndfcflcoemolnggghgoodce)

初心者が扱うには、少し難しいと思いますが、
オンラインゲームを作るつもりの方は、検討する必要があると思います。
フォートナイトでも使われているシステムです。

#環境
バージョン　UE4 4.25.4
ブループリントでサードパーソンプロジェクトを作成したところから始めます。
プロジェクト名：GAS_BP
Microsoft Visual Studio Community 2019


#1. プラグインをオンに
![qiita_gas_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/933e24be-96f1-982e-7e82-1a46ed61452d.jpeg)
【設定】＞【プラグイン】＞【ビルトイン】＞【Gameplay】＞【Gameplay Abilities】
プラグインをオンにして、エディタを再起動します。

#2. 新規C++クラス
![qiita_gas_002.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/81473a6c-0dcc-df6c-2321-cbda3bd1daae.jpeg)
再起動が完了したら、
フォルダ内のどこでもいいので、右クリックから、【新規C++クラス】をクリック。

![qiita_gas_003.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/d3970e37-8327-4d25-4cca-bc99f3cbebd6.jpeg)
【Character】を親クラスに選択して、次へ

![qiita_gas_004.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/4743ca03-5cd9-2e9c-c247-308b86e5f3a3.jpeg)
ファイル名【GAS_Character（任意）】として、クラスを作成。

![qiita_gas_005.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/17528536-b7eb-6622-d7d8-0aa819c2a7fc.jpeg)
Microsoft Visual Studio がインストールしてあり、ライセンスが通っていれば、
Visual Studioが立ち上がると思います。
うまく立ち上がらない場合は、**Visual Studio** の **Professional** や **Community** や **Code** など種類がややこしいので、下記サイトでの説明を見ながら、よくわからない場合はCommunityを使う形が良いのかなと思います。
>[【初心者必見！】Visual Studio Communityについてわかりやすく解説！](https://www.sejuku.net/blog/41148)

Visual Studioが立ち上がり、
GAS_Character.cpp　と　GAS_Character.h が開いたという前提で進めていきます。

一旦UE4のエディタに戻ると、

![qiita_gas_006.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/45b51b56-8c27-042c-1f55-92426c2453da.jpeg)
【C++クラス】というフォルダが増えていて、【GAS_BP（プロジェクト名）】のフォルダの中に、
白い帯の【GAS_Character】がいるのを確認しておきます。
ブループリントでプロジェクトを作った後でも、C++クラスを作成する事で、
後付けでC++プロジェクト(?)として扱えるようになります。

Visual Studioを閉じて、開き方が分からない場合は、
このGAS_Characterをダブルクリックで、開くこともできます。

![qiita_gas_009.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/f31c0acc-f04a-3ac1-f99d-e578be5d87bd.jpeg)
プロジェクト作成時に、C++ではなく、ブループリントでプロジェクトを作った場合は、
ファイルから<font color="Red">**【Visual Studio プロジェクトを更新】**</font>を押しておく必要があります。
この更新をすることで、プラグイン関連などの標準以外のシステムの紐づけがされるようです。
> [参考：UE4 Includeファイルが認識されない場合の対処法 - PaperSloth’s diary](https://papersloth.hatenablog.com/entry/2019/09/23/084612)


#3. Visual Studio 編集
##GAS_BP.Build.cs
![qiita_gas_007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/8be42472-df3b-8faf-a70e-e7ce47f47870.jpeg)
【GAS_BP.Build.cs】をダブルクリック。

![qiita_gas_008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/20f32a09-3f36-4c69-daa0-004308d5ae33.jpeg)
PublicDependencyModuleNames.AddRange(new stringの行に　, "GameplayAbilities"　を追加する。

```
, "GameplayAbilities"
```
下記に追加後の中身を置いておきます。【GAS_BP】の部分は、プロジェクト名なので、プロジェクトによって置き換える必要があります。

```cs:GAS_BP.Build.cs

using UnrealBuildTool;

public class GAS_BP : ModuleRules
{
	public GAS_BP(ReadOnlyTargetRules Target) : base(Target)
	{
		PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs;
	
		PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore", "GameplayAbilities" });

		PrivateDependencyModuleNames.AddRange(new string[] {  });

		// Uncomment if you are using Slate UI
		// PrivateDependencyModuleNames.AddRange(new string[] { "Slate", "SlateCore" });
		
		// Uncomment if you are using online features
		// PrivateDependencyModuleNames.Add("OnlineSubsystem");

		// To include OnlineSubsystemSteam, add it to the plugins section in your uproject file with the Enabled attribute set to true
	}
}
```

##GAS_Character.h
部分的な修正のというわけにいかなかったので、全文載せときます。 
よくわからない人はコピペしてください。

```cpp:GAS_Character.h

#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Character.h"
#include "AbilitySystemInterface.h"
#include "GAS_Character.generated.h"

UCLASS(config = Game)
class AGAS_Character : public ACharacter, public IAbilitySystemInterface
{
	GENERATED_BODY()

public:
	AGAS_Character();

	/** ability system */
	UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = Abilities, meta = (AllowPrivateAccess = "true"))
		class UAbilitySystemComponent* AbilitySystem;
	UAbilitySystemComponent* GetAbilitySystemComponent() const
	{
		return AbilitySystem;
	};
	/** ability list */
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Abilities)
		TArray<TSubclassOf<class UGameplayAbility>> AbilityList;

	/** BeginPlay, PossessedBy override */
	virtual void BeginPlay() override;
	virtual void PossessedBy(AController* NewController) override;

};
```
【GAS_Character】は、別の名前で作成している場合は、置き換える必要があります。
不要な文字列がある場合は、ご指摘いただければと思います。


##GAS_Character.cpp
こちらも、全文載せておきます。
よくわからない人はコピペしてください。

```cpp:GAS_Character.cpp

#include "GAS_Character.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "AbilitySystemComponent.h"

AGAS_Character::AGAS_Character()
{
	// ability system component
	AbilitySystem = CreateDefaultSubobject<UAbilitySystemComponent>(TEXT("AbilitySystem"));
}

void AGAS_Character::BeginPlay()
{
	Super::BeginPlay();
	if (AbilitySystem)
	{
		int32 inputID(0);
		if (HasAuthority() && AbilityList.Num() > 0)
		{
			for (auto Ability : AbilityList) {
				if (Ability)
				{
					AbilitySystem->GiveAbility(FGameplayAbilitySpec(Ability.GetDefaultObject(), 1, inputID++));
				}
			}
		}
		AbilitySystem->InitAbilityActorInfo(this, this);
	}
}

void AGAS_Character::PossessedBy(AController* NewController)
{
	Super::PossessedBy(NewController);

	AbilitySystem->RefreshAbilityActorInfo();
}
```
【GAS_Character】は、別の名前で作成している場合は、置き換える必要があります。
不要な文字列がある場合は、ご指摘いただければと思います。

##C++プロジェクトビルド
![qiita_gas_010.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/de0bda94-7fa2-9725-4018-cb7909b83bba.jpeg)
ビルドから、【GAS_BPのビルド】を選び、今までの処理が間違っていなければ、正常終了すると思います。

![qiita_gas_011.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/e8d69dc0-b4eb-7b5a-bbf4-cd000f9ff958.jpeg)
エラーなどが出る場合は、どこか間違ったことをしている可能性があるので、
再度工程を確認し直してください。

エラー文など、日本語環境の初期状態だと文字化けするようなので、
下記サイトの工程を確認して、文字化けしないようにした方が良いかと思います。
> [UE4開発におけるコンソールログの文字化け対処法 | | シリコンスタジオTECHブログ｜Ideas](https://blog.siliconstudio.co.jp/2021/02/606/)

#4. グレイマンにGAS_Characterを継承
![qiita_gas_012.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/3e444be8-4b02-c1aa-d254-f71fc700773d.jpeg)
ブループリントのThirdPersonCharacterをダブルクリックして、開きます。

![qiita_gas_013.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/906226/b334099d-c2f4-ad0b-464c-062c1217e972.jpeg)
【クラス設定】をクリックし、詳細欄の親クラスに、【GAS_Character】を指定します。

プレイボタンを押して、今まで通りグレイマンが動けば、
Gameplay Ability System の導入としては、完了です。

**で？**

ここまで出来たら、

>[GameplayAbilitiesの使い方(アビリティ編) - おかわりのアンリアルなメモ](https://okawari-hakumai.hatenablog.com/entry/2018/07/30/233345)
>[GameplayAbilitiesの使い方(アトリビュートセット・エフェクト編) - おかわりのアンリアルなメモ](https://okawari-hakumai.hatenablog.com/entry/2018/08/03/082935)
>[GameplayAbilitiesの使い方(タスク編) - おかわりのアンリアルなメモ](https://okawari-hakumai.hatenablog.com/entry/2018/08/04/165742)

>[[UE4]GameplayAbilitySystemでコンボ攻撃を作る｜株式会社ヒストリア](https://historia.co.jp/archives/15422/)
>[[UE4]GameplayAbilitySystemで「スタミナ」を作る｜株式会社ヒストリア](https://historia.co.jp/archives/17941/)

導入後の使い方の記事に目を通していくといいと思います。

#ソースファイル
GitHub上にこの記事の工程を済ませた、データを置いておくので、
どうしてもうまくいかない場合など、確認してみてください。
https://github.com/O-Y-G/GAS_BP

#参考資料まとめ
- 公式ドキュメント
    - [ゲームプレイ アビリティ システム | Unreal Engine Documentation](https://docs.unrealengine.com/ja/InteractiveExperiences/GameplayAbilitySystem/index.html)
    - [GameplayAbilities API | Unreal Engine Documentation](https://docs.unrealengine.com/en-US/API/Plugins/GameplayAbilities/index.html)
    - [Action RPG のゲームプレイ アビリティ | Unreal Engine Documentation](https://docs.unrealengine.com/ja/Resources/SampleGames/ARPG/GameplayAbilitiesinActionRPG/index.html)
    - [猫でも分かる UE4の新しいサンプル「Action RPG」について 76p~](https://www.slideshare.net/EpicGamesJapan/ue4action-rpg)
    - [『Atomic Heart』では Unreal のゲームプレイ アビリティ システムが中心的な役割を果たす](https://www.unrealengine.com/ja/tech-blog/unreal-s-gameplay-ability-system-is-at-the-heart-of-atomic-heart)

- YouTube Unreal Engine 公式
    - [Using the Gameplay Ability System | Unreal Fest Europe 2019 | Unreal Engine](https://youtu.be/_713CSOWkTU) 
    - [Hero AI – Gameplay Abilities Meet Behavior Trees | Unreal Fest Europe 2019 | Unreal Engine](https://youtu.be/1Dm1G6fUuFs)
    - [Action RPG: Gameplay Abilities System | Inside Unreal](https://youtu.be/QZk3tEpZxjU)
    - [A Guided Tour of Gameplay Abilities | Inside Unreal](https://youtu.be/YvXvWa6vbAA)

- GAS情報まとめ
    - [GameplayAbilities and You - Old UE4 Wiki](https://nerivec.github.io/old-ue4-wiki/pages/gameplayabilities-and-you.html) 
    - [Pantong51/GASContent: Repo to gather all Gameplay Ability System content for UE4](https://github.com/Pantong51/GASContent)
    - [tranek/GASDocumentation: My understanding of Unreal Engine 4](https://github.com/tranek/GASDocumentation)
    - [GASDocumentation/README.jp.md at lang-ja · sentyaanko/GASDocumentation](https://github.com/sentyaanko/GASDocumentation/blob/lang-ja/README.jp.md)（日本語翻訳）

- ブログ
    - [GameplayAbilities カテゴリーの記事一覧 - おかわりのアンリアルなメモ](https://okawari-hakumai.hatenablog.com/archive/category/GameplayAbilities)
    - [Gameplay Ability｜ゲーム企画・開発のヒストリア](https://historia.co.jp/?s=Gameplay+Ability)
    - [GameplayAbility カテゴリーの記事一覧 - 愛をもってゲームをつくるゴリラのブログ](http://goolee.hatenablog.com/archive/category/GameplayAbility)
    - [UE4 GameplayAbility Pluginについてのメモ - Qiita](https://qiita.com/unknown_ds/items/6d4438646827bbe08f4a)
    - [Launching Grenades in Unreal with Gameplay Ability System: Part 1 / Habr](https://habr.com/en/post/528360/)

- YouTube
    - [Intro to Gameplay Abilities in Unreal Engine 4](https://youtu.be/Ev2P6BTUxN0)
    - [Gameplay Ability System in 40 Minutes -UE4 C++ Tutorial](https://youtu.be/Yub52f4ZUU0)
    - [Ability System Series](https://www.youtube.com/playlist?list=PL4G2bSPE_8ul-A6UdSBu7OF0dS1dqxble)
    - [Gameplay Ability System Tutorial](https://youtube.com/playlist?list=PLw-lnbqWlRJCYPwesxD36q8bYq_Yv_mMN)
    - [Let's make an MMO in UE4](https://www.youtube.com/playlist?list=PL3eBqMwkHPok1KgYuobV-DeVi9r_0iimH)

- Udemy
    - [Introduction to Unreal Engine 4 Ability System - UE4](https://www.udemy.com/course/introduction-to-unreal-engine-4-ability-system/)

- Twitter
    - [双腕のソルダートGamePlayAbilityに完全移行](https://twitter.com/pafuhana1213/status/1355545027955417090?s=20)
    - [ue4 gameplay abilityを検索](https://twitter.com/search?q=ue4%20gameplay%20ability&src=typed_query)
    - [ue4 gameplay abilitiesを検索](https://twitter.com/search?q=ue4%20gameplay%20abilities&src=typed_query)

- Sample Project
    - [Action RPG：Epic コンテンツ - UE マーケットプレイス](https://www.unrealengine.com/marketplace/ja/product/action-rpg)
    - [New ‘Action Roguelike’ C++ Project on GitHub](https://www.tomlooman.com/action-roguelike-cpp-ue4/)

貴重な情報共有ありがとうございます！

#おわりに
Gameplay Ability System の記事や講演は、ことごとくC++プロジェクトでの作成になっていたため、
インプットやキャラクターの動作まで、C++で書かれると、なんもわからん自分向けに、
C++の部分を最小限にしたいと検証した結果になります。
昔に比べると、GASの情報が増えてきたと思いますが、初心者が扱うには、まだ難しい点が多いので、
なんとかうまく情報共有していければなと思います。

Qiita記事を書くに当たって、こちらの表記方法を参考にさせていただきました。
[**Qiita Markdown 書き方 まとめ @shizuma**](https://qiita.com/shizuma/items/8616bbe3ebe8ab0b6ca1)
ありがとうございます！


こちらに続きます。
[**UE4 Gameplay Ability System で2Dコンボ攻撃（1/2）導入編**](https://qiita.com/O_Y_G/items/30c2d5618a3bdfbd649d)
[**UE4 Gameplay Ability System で2Dコンボ攻撃（2/2）実装編**](https://qiita.com/O_Y_G/items/70ae6f353d06de54d1c1)