[UE5]StateTreeを勉強する クイックスタートガイドを見る（2）

https://dev.epicgames.com/documentation/ja-jp/unreal-engine/statetree-quick-start-guide
いよいよStateTreeを記述する項に入る。書いてある内容と重複する説明もあるが、理解を深めるためにあえて記述する。基本的に一度ガイドのまま作ってみてからこの記事を読むと理解しやすいように書いてある。

# 扱うStateTree概要
クイックガイドで扱うAIは、耐久値が0になるとセットしたオブジェクトをDestroyする非常にシンプルなもの。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/46e6ffe1-b2cf-4fff-184a-154437138629.png)
Idle：オブジェクトが生きている状態。なお、単語の意味的には待機。
Dead：Idle状態でヒット回数が一定以上になったら遷移する。破壊する処理を走らせる。

# 遷移をどう作るのか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/a493d125-8251-a6aa-ef33-660833cb95b1.png)
Idleのノードをクリックすると、右のDetailsに項目が出る。Transitions（遷移の意）の＋マークをクリックすることで、遷移を増やせる。このサンプルでは二つ用意する。

一つ目の遷移
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/6f4c3b4f-b567-de8a-ccfc-bb4275acfc04.png)
* Trigger：遷移するタイミング
On State Completed：このステートが完了したとき
* Transition To：遷移先のステート
Root（大本のステート）

Idleステートは何もしないので毎フレーム完了する。Rootは即Idleに遷移するので、これだけだと一生行ったり来たりすることになる。

二つ目の遷移
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/2d53897f-6a7e-2638-931b-33e08d113664.png)
* Trigger / On Tick：ステートにいる間は毎フレーム
* Transition To / Dead：Deadに遷移

毎フレーム遷移チェックが走るようになっている。
Priority,Delay～～に関しては今回は触れない。（あるのは初期値）

重要なのはこの下のConditions（条件）の方だろう。こちらも＋ボタンで追加する。内容を要約すると、StateTreeを組み込んだActorのHitCountが5以上になるとTrueになる。
* IF：条件式の指定
Integer Compare：整数型の比較
* Invert：条件式の反転。NOT。
* Operator：条件式の演算子。＝や＜など。
Greater or Equal：≧
* Left/Right：左辺/右辺 変数や数値を指定できる。

ここでの鬼門はActorのHitCountにどうアクセスするかだろう。

まず、BP_ShootingTargetの変数にHitCountがある必要がある。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/6c990c30-da17-81d2-f2b7-a96ff3d89b8b.png)
ここに設定したうえでST‗ShootingTarget側で
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/dd6274ad-bb39-a332-4734-04080043ce29.png)
Schema>Context Actor ClassにBP_ShootingTargetを指定する。これでLeftの右端のマークを押すことでActor>HitCountと選べるようになるはずだ。出ない場合は両ファイルのCompileを押してみよう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/47615952-188a-246a-2957-2d0705992c3e.png)

# 実際に挙動を行わせるには
これだけだとステートを遷移するだけで、ゲーム内世界には何も起きない。

まずBP_ShootingTargetでHitCountを増やす。これは接触イベントをトリガーにして加算している。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/51e6e575-c80a-5758-1ee1-67df38af9d2d.png)

またDelayedDestroyというイベントを用意しておく。内容は「0.2秒待って、自壊する」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/dccfd72d-664e-3028-143f-11da64b132ef.png)

これでカウントとオブジェクトの破壊は出来た。ST‗ShootingTargetのDeadステートでDelayedDestroyを呼べれば完成だ。

# タスクの呼び方
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/9634c7d9-04bf-0bdf-9edc-afc73b15cc3d.png)
実際に行う処理はタスクとして別ファイルに記述する。基本的なものについては最初からある。Deadで行うタスクは3つある。上から順番に行っているように見えるが、実は全部同時に起動している。
* Debug Text Task：既存のタスク。デバッグテキストを出す。
* Delay Task：既存のタスク。指定秒数Delay（遅延）させる。
* STT Destroy：自作するタスク。BP側のDelayedDestroyを発生させるためのタスク。

作り方に関してはガイドに任せて割愛するとして、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/b6271adc-24b1-9481-681d-c2c5bf4823db.png)
Event ExitState（ステートから出る時のイベント）でDelayedDestroyを起動している。DelayTaskが入っているため、結果的にはそれを待って動く。
ここのActorという変数だが、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/e83b40aa-e51c-9fc3-364c-b17327e6f533.png)
Contextの下に無いとダメなようだ。StateTree側のContext>Actorとうまく連動できなくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3934437/a6c59fd0-9dbe-afe2-084e-850892ced864.png)
ActorのDetailのCategoryの欄にContextと記述しよう。

最後にST‗ShootingTargetをBP_ShootingTargetに入れて、BP_ShootingTargetをレベル配置する。これで銃を拾って5回撃つことで破壊できるようになるはずだ。