UE4の勉強記録

UE4の勉強の記録です。個人用です。

12章9,10,11節 GameplayAbilities API-テスト

<前文>

f:id:kazuhironagai77:20190210122704p:plain

<本文>

<目的>

今回は、9,10,11節のレシピをGameplayAbilities and You (Unreal Wiki)の実装を参考にして実際に動くがテストします。

9節のテスト>

<方法>

このレシピは、単にThird Personのテンプレートからプロジェクトを作成すればいいと考えられます。ので新しいプロジェクトをThird Personのテンプレートから作成します。ので全部やり直します。

f:id:kazuhironagai77:20190217201808p:plain

しました。

f:id:kazuhironagai77:20190217201824p:plain

しましたが、何故か今回はエラーに成ってしまいました。

色々調べたのですが分からない。前回は普通に出来たのに、何で?とかなり焦ったのですが、原因は、"GameplayTags", "GameplayTasks"をBuild.csファイルに入れなかったからでした。

f:id:kazuhironagai77:20190217201840p:plain

GameplayAbilities and You (Unreal Wiki)では、"GameplayTags", "GameplayTasks"は使用していないので、今回は抜いてみたのですが、これらのモジュールが必要でした。

f:id:kazuhironagai77:20190217201907p:plain

コードからでは、GameplayAbilityクラスを使用するのにTaskモジュールらを必要としているようには見えませんね。

f:id:kazuhironagai77:20190217201926p:plain

f:id:kazuhironagai77:20190217201934p:plain

前回(12章9節 part3)と同じようにします。(CanActivateAbility、CheckCost、ActivateAbilityそしてInputPressedメンバー関数のみを追加します。)

f:id:kazuhironagai77:20190217201951p:plain

ビルドも成功しました。

f:id:kazuhironagai77:20190217202015p:plain

前回と同じやり方で派生します。

f:id:kazuhironagai77:20190217202031p:plain

f:id:kazuhironagai77:20190217202044p:plain

しました。

f:id:kazuhironagai77:20190217202100p:plain

f:id:kazuhironagai77:20190217202109p:plain

名前も前回と同じ、WarriorGameplayAbilitySetにしました。

f:id:kazuhironagai77:20190217202124p:plain

f:id:kazuhironagai77:20190217202132p:plain

しました。

f:id:kazuhironagai77:20190217202148p:plain

前回は、GameplayAbility_AttackのBPの名前がBP_GameplayAbility_Attackだったので直します。

f:id:kazuhironagai77:20190217202226p:plain

f:id:kazuhironagai77:20190217202241p:plain

前回は、ここで新しいアクタークラスからの派生クラスであるWarriorクラスを作成し、その中で実装しました。今回は、既に実存しているキャラクタークラス内から実装していきます。

f:id:kazuhironagai77:20190217202259p:plain

f:id:kazuhironagai77:20190217202306p:plain

ビルドすると成功しました。

f:id:kazuhironagai77:20190217202342p:plain

更に、UE4エディター上で、Third Person Characterを選択し、DetailsからGameplay Ability Setを探して、WarriorGameplayAbilitySetを選択しました。

f:id:kazuhironagai77:20190217202402p:plain

前回は、個々の部分はスキップしましたが、今回は実際のThird Person Characterが既に存在しているので、実行出来ました。

この時点でplayをしてみると、

f:id:kazuhironagai77:20190217202430p:plain

エラーもなく動きます。

f:id:kazuhironagai77:20190217202451p:plain

以下に示すコードを加えます。

f:id:kazuhironagai77:20190217202508p:plain

f:id:kazuhironagai77:20190217202515p:plain

f:id:kazuhironagai77:20190217202523p:plain

f:id:kazuhironagai77:20190217202531p:plain

ビルドします。

f:id:kazuhironagai77:20190217202552p:plain

成功しました。

f:id:kazuhironagai77:20190217202622p:plain

前回と同じです。ここでやる事は特にないので次へ行きます。

f:id:kazuhironagai77:20190217202640p:plain

前回はサンプルコードからまるまるコピーしましたが、その後で教科書もコードを提供している事に気が付きました。今回は教科書のコードを使用します。

<AbilitySystemComponentについて>

まず、以下のコードを追加しました。

Headerファイルに、

f:id:kazuhironagai77:20190217202719p:plain

sourceファイルのコンストラクター

f:id:kazuhironagai77:20190217202744p:plain

を追加しました。Third Person Characterのコンストラクターのパラメーターは、FObjectInitializerクラスから作成したオブジェクトをパスしていないので、この部分はコードを多少変えました。以下にサンプルコード並びに教科書が提供する変更前のコードを示します。

f:id:kazuhironagai77:20190217202850p:plain

正直、この二つの違いについては良く分かっていません。ここでは同じものとして扱っています。

f:id:kazuhironagai77:20190217202925p:plain

ビルドは成功しました。

f:id:kazuhironagai77:20190217203002p:plain

Playも問題ないようです。

更に、以下に示すコードを追加しました。

f:id:kazuhironagai77:20190217203023p:plain

ビルドしてplayしましたが、問題なく出来ました。

<Errorについて>

以下のコードとそれを実装するのに必要なコードを足しました。

f:id:kazuhironagai77:20190217203101p:plain

Error関数を実装するために必要なコードはサンプルコードのLogファイルにすべてありました。GameplayAbilities APIとは関係ないので、実際のコードは省略します。

<FGameplayAbilitySpec>

FGameplayAbilitySpecクラスのオブジェクトSpecを初期化しました。

f:id:kazuhironagai77:20190217203139p:plain

<FGameplayAbilitySpecHandle>

FGameplayAbilitySpecHandleクラスのオブジェクトabilityhandleを初期化しました。

f:id:kazuhironagai77:20190217203225p:plain

<int32 AbilityID>

int32 AbilityIDを初期化します。

f:id:kazuhironagai77:20190217203246p:plain

<FGameplayAbilityInputBinds>

FGameplayAbilityInputBindsクラスのオブジェクトinputBindsを初期化します。12章4節で述べたようにFGameplayAbiliyInputBindsでなく、FGameplayAbilityInputBindsで初期化します。

f:id:kazuhironagai77:20190217203310p:plain

<BindAbilityActivationToInputComponent>

UAbilitySystemComponent クラスのBindAbilityActivationToInputComponentメンバー関数を使用して、アビリティのActivation をInputComponentにバインドします。

f:id:kazuhironagai77:20190217203332p:plain

<TryActivateAbility>

UAbilitySystemComponent クラスのTryActivateAbilityメンバー関数を使用して、Active状態のアビリティを始動させます。

f:id:kazuhironagai77:20190217203415p:plain

<結果>

コンパイルしてplayすると、以下に示すように見事にプリントアウトされました。よってUGameplayAbility_Attackクラスの関数が呼ばれている事が確認出来ました。

f:id:kazuhironagai77:20190217203438p:plain

<考察>

結果に記されたoutput logにプリントアウトされたメッセージからGameplayAbilityクラスの役割がはっきりと分かりました。

output logにプリントアウトされたメッセージを見るとCanActivateAbility()関数→ActivateAbility()関数→CheckCost()関数が呼ばれています。

Gameplay Ability Systemによれば、GameplayAbilityクラスでは、まずTryActivateAbility()関数が呼ばれ、CanActivateAbility()関数そしてActivateAbility()関数の順番に呼ばれるそうです。

この結果を見ると、その通りに呼ばれているみたいですね。

TryActivateAbility()関数が実際に呼ばれているか確認したいですね。

以下に実際のコードから見つけたTryActivateAbility()関数の宣言部を示します。

f:id:kazuhironagai77:20190217203503p:plain

これを見ると、FGameAbilitySpecHandleのみパスすればいいみたいですね。試してみます。

f:id:kazuhironagai77:20190217203537p:plain

ビルドして、playしてみます。

f:id:kazuhironagai77:20190217203555p:plain

変わらない。あれ?

うーん。ひょっとしてブループリントから新しく作成しないといけないのかも。

f:id:kazuhironagai77:20190217203610p:plain

更に、WarriorGameplayAbilitySetの設定も以下に示すように変えました。

f:id:kazuhironagai77:20190217203629p:plain

Playしてみると、

f:id:kazuhironagai77:20190217203648p:plain

うーん。変わってません。

何かちょっといじれば直るような気がしますが。Gameplay Ability Systemに参考になる事が書かれていないか読んでいましたが、ウーン深い。これはこれでしっかり勉強する必要があるみたいです。ActionRPGを使用したgameplay Ability Systemのチュートリアルは更に深い内容を教えるみたいです。これは、もっと勉強してから考えた方がいいかもしれません。

これで終わりにしようとした所で、Warriorクラスを見てたらTryActivateAbility()関数はUAbilitySystemComponentクラスのメンバー関数でした。

f:id:kazuhironagai77:20190217203713p:plain

はあー。こんな基本的な事を間違えるとは。GameplayAbilityクラスからTryActivateAbility()関数を呼べるわけはないです。

10節のテスト>

「12章第10節 GameplayAbilities API -UAttributeSetを使用して状態(stats)を実装する。」をテストします。

<方法>

9節のテストで作成したプロジェクトにそのまま足していきます。

f:id:kazuhironagai77:20190217203904p:plain

既にやっています。

f:id:kazuhironagai77:20190217203920p:plain

12章10節で行った方法と同じ方法で作成します。

f:id:kazuhironagai77:20190217203952p:plain

追加したコードを以下に示します。

f:id:kazuhironagai77:20190217204009p:plain

f:id:kazuhironagai77:20190217204016p:plain

f:id:kazuhironagai77:20190217204024p:plain

f:id:kazuhironagai77:20190217204031p:plain

12章10節で行った方法と同じ方法で作成しました。

f:id:kazuhironagai77:20190217204047p:plain

f:id:kazuhironagai77:20190217204136p:plain

残りは、12章⒒節のテストで行います。

<結果>

これで、追加出来たのでしょうか?

Playをしてみると、PostInitializeComponents()関数が呼ばれているのが分かります。

f:id:kazuhironagai77:20190217204202p:plain

ので、UGameUnitAttributeSetはAbilitySystemComponentにバインドしたはずです。

11節のテスト>

「12章11節 GameplayAbilities API-GameplayEffectによるバフ(buff)の実装」をテストします。

<方法>

10節のテストで作成したプロジェクトにそのまま足していきます。

f:id:kazuhironagai77:20190217204225p:plain

11節と同じ方法でやりました。Third Person Characterクラスには、BeginPlay関数がないので、コンストラクターのすぐ後で実装しました。

f:id:kazuhironagai77:20190217204242p:plain

f:id:kazuhironagai77:20190217204250p:plain

まず、AddModifier()関数を実装しました。

f:id:kazuhironagai77:20190217204305p:plain

AddModifier()をTestGameplayEffect()関数内で使用します。

f:id:kazuhironagai77:20190217204331p:plain

f:id:kazuhironagai77:20190217204338p:plain

11節でやったのと同じように、サンプルコードからコピーします。

f:id:kazuhironagai77:20190217204356p:plain

f:id:kazuhironagai77:20190217204404p:plain

サンプルコードのままにコピーしました。

f:id:kazuhironagai77:20190217204419p:plain

11節はこれで終わっていますが、明らかにこれだけでは、TestGameplayEffect()関数は実行されません。サンプルコードを見たらPostInitializeComponents()関数内で呼ばれていました。

ので、TestGameplayEffect()関数をPostInitializeComponents()関数内に加えました。

<結果>

ビルドしてplayすると普通に動きますがHpが変化したのかどうかは全く分かりません。確認するためにはThird Person CharacterのHpを表示する方法が必要です。

色々調べたのですが簡単には分かりませんでした。

はっきり言って別なチュートリアルで最初から勉強した方が速いみたいです。のでここで確認作業は中止します。

<まとめ>

GameplayAbilities and You (Unreal Wiki)の実装を利用して12章9,10,11節のGameplayAbilities APIのレシピが正しく動いているか確認しました。しかし完全に確認出来たのは12章9節だけでした。

他のチュートリアルを良く勉強したら10,11節の確認方法も判明しそうだったのですが、この教科書を勉強するのが目的で、GameplayAbilities APIを学ぶためにこの教科書を読んでいるのではないので止めました。

マルチプレイのアクションゲームの製作をするならば、GameplayAbilities APIの勉強は必須かもしれませんが、それ以外の場合はどこまでGameplayAbilities APIの勉強すべきかを見極めるのも大切な気がします。

最後に、私のこのレシピに対する評価を簡潔に述べたいと思います。

まず、コードがきちんと動いている事が確認出来ません。これは大きなマイナス点です。

次に、初心者でも理解出来る様に最低限のみ教えています。この点に関しては、他のチュートリアルと比較しても、かなりいいと思いました。

このレシピのみでGameplay Abilities APIの基礎を理解する事は出来ないと思います。しかしGameplay Abilities APIの使用方法を理解したい人が、勉強しないといけない教材の一つではあると思います。