シームレスなカットシーンを実現するために

https://twitter.com/koorinonaka/status/1597537690429575170

まずは今回作った動画から。ボス登場演出的なやつ。

# インゲームのカメラとブレンドする
カット開始/終了のフレーム区間でカメラをブレンドする機能。
![8e07e444e4ce9d99daef4edf36294d6a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/93b3087d-9247-e77f-9937-8b11947afdc6.png)
カメラカットでメニューを開き `ブレンド可能` にチェックを入れると、カットの前後でブレンド区間が設定可能になります。
![5c74ed71bcb04bc1e93cc0bf36511ecd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/035088af-4878-72ad-1d59-95cc76a994cc.gif)
カット端の左上＆右上でドラッグする（実際かなり押しづらいがｗ）。

https://historia.co.jp/archives/16506/

複数のカメラカット間でもブレンドできます。詳しくはヒストリアさんの記事でどうぞ。

**やったこれだけでブレンドできたぞ！！すごい！！！**

## インゲームで再生したときにレターボックスが表示される
![b0361270b532a67e76ba337c6d1eee98.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/e436dd98-0aff-234b-a026-6e481d1130ef.gif)
ブレンド区間で左右が黒く塗りつぶされる場合があります。
![6d574f990957ec6a7a25d9e5703e4464.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/b906154a-6746-dc47-196b-22d1500045cb.png)
`CineCameraActor` の `ConstrainAspectRatio` がデフォルトで ON になっているため。明示的に OFF にしましょう。

# ゲーム内のアクターで置換する
レベルシーケンス内のアクターを、ゲーム側でスポーンしたアクターに置き換える機能。
![c323ebc0ebd337091fe70622d80814ef.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/3940ce45-794f-3d7e-77ca-54a437c2dc96.png)
まずはシーケンサ内にキャラクターを追加します。
コンテンツブラウザから、シーケンサのウィンドウにドラッグするだけで OK。

:::note info
SkeletalMesh ではなくゲームでスポーンする BP を配置する。
回転軸の変換や、コリジョンによる接地などがそのまま反映されるため。
:::

:::note warn
Possessable ではなく Spawnable の状態にする必要があります。アイコンに雷マークついてるやつ。
:::

## 置換するアクターにタグをつける
![224e96de5c4b83b97d7071ca09a2a9f9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/5fa5c4d9-ee42-a252-7d7c-779a8b17417a.png)
バインドするアクター毎にタグを追加する。
![4fefaf79392cbb1d2e837c9b50f82d77.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/d62f88f9-b542-b8d3-9524-b6f344a6e1c2.png)
ここで入力した名前が、BP での指定に使われます。分かりやすい名前をつけてあげましょう。

## Blueprint でバインドを指定する
![8b7d71fe05750fe0af37b8e83b5b91fe.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/a851eea1-a038-b31a-20bb-4a75e0125b68.png)
`LevelSequenceActor` に対して `AddBindingByTag` でアクターをバインドする。これでシーケンサ内で操作していたアクターはスポーンされなくなり、ゲームのアクターにトラックが反映されるようになる。Boss アクターは予め適当な場所にスポーンさせておく。
しかしこのままでは、シーケンサが終了すると同時にアクターは元の状態に戻されてしまいます。トランスフォームトラックの項で後述。

# アニメーショントラックの設定
![94640db33661b7ffe8737b69c15e611d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/3fe38028-067d-f9c7-63d2-9f4da1003eaa.png)
シーケンサで再生するアニメーションを `アニメーショントラック` に追加します。

:::note info
BP 内に複数の SkeletalMesh が存在する場合は、追加するトラック一覧に `アニメーショントラック` が表示されません。
CharacterMesh0 など、メッシュのトラックを追加した上で、改めてアニメトラックを追加する必要があります。
:::

`AnimMontage` は未対応、`AnimSequence` or `AnimComposite` のみ指定することができます。
![163337eceb98a7cd74d827f9aa7a229d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/5af4346e-112e-d69c-57f4-b69fd5722967.png)
アニメトラック内でブレンドやアニメ尺を調整することも可能。
ていうかこの機能 AnimComposite にも欲しい。。

## RootMotion を利用したい
RootMotion の移動値を反映させたい場合。以下の方法があるようです。

### Sequencer Non-Linear Animation (NLA) Tools (Beta)
https://twitter.com/pafuhana1213/status/1347597132782399489

しかしアクターを置換する場合など、`SkeletalMeshComponent` の `AnimationMode` が `UseAnimBlueprint` になっている場合はルートが動いてくれない。
![7dd3fdb9d284fecf1a81ba161cb9dd3b.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/ac29a6d0-266c-987e-b855-f601fc4c099e.png)
`ForceCustomMode` にチェックを入れれば動くのだが、実際に更新されるのはメッシュ本体だけで、アクター自体はその場で停止する。`SwapRootBone` を指定しても座標軸がズレたり、期待した動作にはならなかった。

### アニメーションルートからインポート
![43a785ef14b6426d64828b27ae2a6dad.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/72e0eef4-e98e-f9b4-2086-d2b1660dd420.png)
トランスフォームトラックは AnimSequence から RootMotion をインポートすることができるらしい。しかしやはりメッシュ本体の座標軸で動作するなど、期待した動作には（ｒｙ。結構古い機能で今後廃止になっていく感じがする。

この辺は沼ってるので詳しい人教えてください。今のところはトランスフォームをそれっぽく打ち込むことにしてます。。

# トランスフォームトラックの設定
![be47de65abc8cc6f177803e02ad467dd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/4fa59412-d87b-fee5-7c6f-57ce9dca4c58.gif)
バインドしたアクターのトランスフォーム（＆アニメ、その他）は、シーケンサの停止とともに元の状態に戻されてしまう。
![c082ee6bf163fdcae80dc4ff84c739b4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/e7cd7722-dcd9-fa4f-910c-fff815ae466e.png)
トラックから `セクションの編集`、`WhenFinished` を `KeepState` に変更することで、状態が維持されるようになる。シーケンサの最後の状態をゲームに引き継いでくれます。

## 途中からトランスフォームを反映させたい
シーケンサの途中で指定位置にテレポートするなど。サンプル動画の後半プレイヤー位置を参照。
![b4d6dd83e7d9b318161024187a06caaa.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/adbb167b-4c75-88d7-c90c-3db5bbe652a1.png)
キーを打つと左右にトラックが伸びた状態で保存されます。このときキーの前後、全てのフレームで左右端の値が反映されます。つまりプレイヤーは最初のフレームから指定位置にテレポートすることになる。
![ad3af64d1be3c6c18cafc9032c7996b7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/630af051-506f-fe3d-bf69-2d3d78f9e6f8.png)
トラックメニューから `編集` `セクションの左側をトリム` を実行すると、左側のトラック区間を切断し、値の反映を無効化することができます。
![4e35cf85b19a49ac478cf59340bf446a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/08cd60f8-c86e-2f76-aebd-267e88880bda.png)

# その他やっておくとよさそうな設定

## ブレンド終了時のカメラ位置はリセットしておく
イベントトラックなどからカメラの位置をリセットする。してない場合は再生前のカメラ状態のままブレンドされる。

# MovementMode を Flyng に変更する
分かりづらいですが、今回の動画では敵キャラが一部で浮遊しています。シーケンサエディタ再生上では問題ありませんが、ゲーム内では Pawn の挙動そのままで接地してしまい、望んだカットにならないことも。

## シーケンサ再生時は AI を止める
![e5ee464ff6aae11d6c9e8cf37bdfb280.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41105/ab763ae6-bdbb-4dec-0133-7183229d6255.gif)
停止しないと、アニメ再生が同時にブレンドされてキモい感じに。
```C++
void AMyAIController::SetLogicPaused( bPause )
{
	if ( UBrainComponent* BrainComp = GetBrainComponent() )
	{
		FString Reason( TEXT( "from SetLogicPaused" ) );

		if ( BrainComp->IsRunning() )
		{
			if ( bPause )
			{
				BrainComp->PauseLogic( Reason );
			}
		}
		else
		{
			if ( !bPause )
			{
				BrainComp->ResumeLogic( Reason );
			}
		}

		BrainComp->RestartLogic();
	}
}
```
やり方は色々あるだろうけど、AI の一時停止。`PauseLogic` などは BP 公開されてないらしい。。