[UE5] MotionWarping Shallow Dive

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">MotionWarping組み込んでみた。位置を移動する仕組み自体はシンプルなんだけど、結局難しいのはコリジョン検知だな。。。<a href="https://twitter.com/hashtag/UE5Study?src=hash&amp;ref_src=twsrc%5Etfw">#UE5Study</a> <a href="https://t.co/nyH7YMvKbJ">pic.twitter.com/nyH7YMvKbJ</a></p>&mdash; koorinonaka (@koorinonaka) <a href="https://twitter.com/koorinonaka/status/1412424231141449742?ref_src=twsrc%5Etfw">July 6, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
UE5 から追加された [MotionWarping](https://docs.unrealengine.com/5.0/ja/AnimationFeatures/MotionWarping/) について浅瀬でちゃぷちゃぷしたメモ。

# MotionWarping とは
>Motion Warping (モーション ワープ) は、キャラクターのルート モーションをターゲットに合わせてダイナミックに調整できる機能です。

[「古代の谷」サンプル](https://docs.unrealengine.com/5.0/ja/ContentAndSamples/ValleyOfTheAncient/#motionwarping) では「キャラクターが障害物を飛び越えていく場面」にて機能紹介されていましたが、インタラクトでポイントに体を向けながら近づく、敵のレーザービームを避ける、においても使われています。
[公式ドキュメント](https://docs.unrealengine.com/5.0/ja/AnimationFeatures/MotionWarping/#%E7%B5%90%E6%9E%9C)では攻撃距離の調整について紹介されてたりで、汎用性がありますね。
ゲームで目標位置に向かって移動する実装は非常に多いので、エンジン側で機能が用意されるのは嬉しいですね！

## MotionWarping 動かない、検索。
この機能はルートモーション前提で作られています。
![eae9ee3f36b605c0c509ba1f1518fc92.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/7ae92876-e8a1-2d0c-f38c-e8fc2b2d20a0.png)
AnimSequence の EnableRootMotion にチェックが入ってないと動作しません。
![cadf604ae1b206d575c7251c8a472eaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/322ac2bb-c837-9e02-e4a2-399bc6eb9eee.png)
そして RootMotionModifierConfig の "AdjustmentBlendWarp" 以外は、**アニメにルート移動値が含まれていないと動きません。**
"SimpleWarp" はルート移動の [現在/総フレーム比率（指定区間）] により位置を計算する実装となっており、そもそも移動値が含まれていないと結果はゼロとなってしまうため。

### AdjustmentBlendWarp を使った詳しいチュートリアル
[[UE5] Motion Warpingでアニメーションによる移動量を自由にコントロール！](https://historia.co.jp/archives/20586/)
いつもお世話になっております。
InPlaceAnimation の場合は AdjustmentBlendWarp を使いましょう。

### 縦移動ができない問題
![2021-07-07-18-50-33.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/c3f07960-82f6-a5a2-62a1-d96bdbc54cdf.gif)
設定には "Ignore ZAxis" があり、デフォルトではオンになっています。
![ae10ff9153ad395ca558f0acbf7c6ba4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/6b3e271b-e185-73a6-4b69-f0b3989b80fc.png)
>平行移動の Z (アップ/ダウン) コンポーネントをワープするかどうかを指定します。

これを有効にした場合、キャラクター自身の CharacterMovementComponent による制御と衝突してしまい、そのままでは縦方向に動きません。
![BP_GA_FunctionTest-EventGraph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/2dbc6ab6-fd92-c382-47dd-eb079f9a2f96.png)
移動区間は MovementMode を Flying にするのがよいでしょう。

### RotationType: "Facing" が動かない問題
>同期ポイントの回転に一致する、または同期ポイントに向くように、回転をワープするかどうかを指定します。

RotationType が Facing の場合、初期地点から目標地点に向けてキャラクターを回転させます。
なのですが、AdjustmentBlendWarp の場合 RotationType の初期化がされてません。エンジンの修正を待ちましょう。

## シンプルに移動するだけの機能？
AdjustmentBlendWarp ってリニア移動だけなの？アニメに合わせて移動するだけなら、モンタージュ通知からの移動処理を作ればいいのでは？
![facc451c5269b10fcbcc7568ca00de19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/e162e93f-1834-b8c4-1e8d-c79922d15cb9.png)
などとも考えましたが、実際やってみると "アニメに合わせた移動値" を設定するのもなかなか大変です。
簡単な平行移動くらいならなんとかなるが、インタラクション性があるアニメなど、複雑なものはアニメ側でつけてもらう方が、自然でよりよいワークフローとなるでしょう。
EnableRootMotion チェック外すマンでしたが、これからは RootMotion と仲良くなれるよう精進したいと思います。