UE4 アニメ―ション管理についてのメモ

# 概要
UnrealEngineのアニメーション管理についてのメモです。
アニメ―ションシーケンスをステートにしてステートマシンを組むと煩雑になってしまうのを何とかできないか、と試してみた記録です。

アニメ―ションシーケンスを変数化して再生するケースとステートマシンを複数持って分散しブレンドポーズさせてみるケースを書いています。

## 修正履歴
|日付|内容|
|:---|:--|
|2019/10/10|ステートマシン切り替え時の注意点を追記|

## 環境
Windows10
Visual Studio 2017
UnrealEngine 4.22


## 参考
以下を参考にさせて頂きました。ありがとうございます。
http://unrealengine.hatenablog.com/entry/2016/03/28/221426


# ステータス内でシーケンスを直接再生
アニメーション再生ノードにて、アニメ―ションシーケンスを引き数にして入れ替え可能にしてみます。

## ステータスの修正
通常、アニメーション再生をする場合のステート内はアニメ―ションシーケンスノードからアウトプットノードへつなぐようになっています。
![state_playanim.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/588c5326-ce27-e0a1-9571-9399af077ddd.png)

[Settings]の[Sequence]を書き換え可能にし、[変数に昇格]させて、[PlayAnimSeq]と名前をつけます。
![state_playanum2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/ac7ebeea-1810-91cf-2e37-0fa5c7ef8303.png)

## アニメ―ションシーケンステーブルの用意
[AnimSequence]型のテーブルを用意して各アニメーションを割り振ります。
![table_detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/631f4fb3-3710-f8c3-91c9-50caaa445560.png)

## アニメーション再生用ブループリント
指定したアニメーション番号から再生できるような関数ブループリントを作成します。
![PlayAnumBP.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/989b52ae-0e4d-c499-b75d-48e7da1505d7.png)
先に変数にした[PlayAnimSeq]へ入れます。


## ステートマシンの設定
ブーリアン変数[IsSetAnim]がtrueになったらステート移動,falseなら戻すように遷移ルールを設定します。

![single_state.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/187ac8b4-8b98-2335-be82-0c48fe8e6a16.png)

ブループリント関数を実行することにより、ステートに設定されている「アニメ―ションシーケンスを再生」ノードにはいるアニメ―ションシーケンス変数にデータが設定されることにより再生できます。



# ブレンドポーズによる管理
ステートマシンを複数使い、変数で切り替え管理しブレンドポーズノードでアニメーションを出力させてみます。

## Enumの用意
アニメーションBPの親クラスのC++側にEnumの定義を用意します。
BluePrintの列挙型でも可。

```cpp:MyAnimInstance.h
// ステータス
UENUM(BlueprintType)
enum class ECharaState : uint8 {
	ST_NONE		UMETA(DisplayName = "None"),
	ST_IDLE		UMETA(DisplayName = "Idle"),
	ST_ATTACK	UMETA(DisplayName = "Attack"),
	Num         UMETA(Hidden)
};
```

定義したEnumを変数で持ちます。

![var_state.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/6fe5f1c5-6f21-9944-77da-da869c841d52.png)


## アニムグラフの設定
定義したEnumに対するブレンドポーズが選択できるのでブループリントを作成していきます。

![blendpose_node.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/c86fa597-6408-20b8-e3b6-078b3993b7e1.png)

入力の[ActiveEnumValue]は先ほど作成したEnumの変数を繋ぎます。
各ポーズは各ステートマシンを作成して繋ぎます。

## ステートマシンの設定
各ステートマシンはそのステート内でアニメーションをセットするだけにします。さらに細かいステートがある場合はサブステータスを追加して分岐させます。
ステートマシン1つ目。
![Idle_SM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/ffec758e-e95b-da64-2cd1-28fdcb043d95.png)

ステートマシン2つ目。細かいサブステートがある場合は下のような感じです。
![Attack_SM.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/6d4540a3-53b8-6129-457e-07310add8eea.png)


アニムグラフの状態は最終的に以下のようになります。
![BlendPose.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/b5aeab04-2b14-57a8-31ab-6ae36d217f2b.png)

複数ステートマシンでアニメーションをブレンドポーズを使って設定されます。ステータスは ECharaState の変数のみで切り替えます。

### ステートマシン切り替え時の注意点
高速でステートマシンを切り替えた時、切り替えたステートマシンのステートがリセットされない（アニメーションが以前の途中から再生される）場合があります。（ステートマシンAからステートマシンBへ切り替えてすぐステートマシンAへ戻すような場合）
これはステートマシンのステートがリセットされるタイミングがブレンド終了時に行わるため、ブレンド終了する前に切り替えて戻すと前のアニメ―ションのままとなってしまいます。

明示的にステートマシンのステートをリセットすることができないため、ブレンド時間を0にするか、スロットアニメ―ションなど別の方法でアニメ―ションを割り込ませるようにしないとならないようです。

トランジッションのブレンド時間設定を変える方法を採る場合は以下の値を小さくすることで実現できます。
![Transition_Blendsetting.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/56becd8c-6dd3-6391-419b-1af58fac530e.jpeg)



# 追記：イベント
アニメ―ションシーケンスに追加する通知以外にステートとトランジションにイベントを追加できます。

## ステート
各ステートにはデフォルトでイベントを設定可能です。
![state_detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/a8f76161-ccf0-3cbe-875c-923edd6031b6.png)

**ステート開始イベント** はステートに遷移した時。
**ステート離脱イベント** は別のステートへ遷移する時。
**ステートブレンド完了イベント** は前のステートとのアニメ―ションブレンドが完了した時。

1ステートに1アニメ―ションを設定した場合は、そのままアニメーションの終了が離脱イベントで取得できますので、いちいちアニメ―ションシーケンスで通知を追加する必要はありません。

## トランジション
各トランジションにもイベントが設定可能です。
![transision_detail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/303806/d1deba89-8118-db6a-7e30-11f7c88c07b2.png)

**トランジションイベントを開始** はステートが遷移条件を満たして移行開始時。
**トランジションイベントの終端** はステートが遷移し終わった時。（元のアニメーションがブレンドし終わったとき？）
**トランジションイベントを中断** はステートが遷移途中で遷移条件を満たさなくなった時。


# まとめ
ステートマシンを複雑化させないようにしたいですが、どうしても複雑化してしまうのでもう少しいい方法を探したいです。
次の方法としてはGameplayTagを使うとよさそうなので調べてみたいと思います。:mag: