執筆バージョン: Unreal Engine 4.20
|
こんにちは。
私はシーケンサー自体の作業をすることはありましたが、
それをゲーム側で呼び出すなどのブループリント周りの作業を行ったことがありませんでした。
今回の記事は、シーケンサーを作成したけれども、ブループリントをあまり触ったことが無く、
ゲーム中での使い方が分からない…といった方の助けになればと思います。
今回はゲーム開始前にシーケンサーを呼び出す方法、そのときに起こった問題と解決方法などを紹介しようと思います。サンプルのプロジェクトはぷちコンでグループ制作したものになります。
今回の目標とするシーケンサーを再生するタイミングとしては以下のようにタイトルとゲーム本編の間になります。

このゲームのレベルの構成や遷移については以下のようになります。

ではまず、シーケンサーがない状態でのゲームプレイ動画です。
シーケンサーがない状態のプレイ動画
ここにシーケンサーを追加して以下のようにするのが目標です。
シーケンサーを追加した状態のプレイ動画
では順に解説させていただきます。
1.ゲーム開始前にシーケンサーを呼び出す
ゲーム本編が開始する前に処理を入れたいので、ゲーム本編が開始する処理が書かれているレベルブループリントを開きます。(今回はこのレベルをゲーム本編のレベルと呼びます)
現在ゲーム開始前は以下のようなレベルブループリント(以下BPと略します)になっています。

(※ゲームモードにはゲームシステムのさまざまな処理、今回の場合はUIを表示更新したり、ゲームがクリアしたかを判定したり、プレイヤーの入力をコントロールしたりなどが入っているため、ゲームモード自体の説明は省かせていただきます。)
まずシーケンサーを再生するには、シーケンサーのカメラを呼び出さなければなりません。
今はプレイヤーのカメラになっていますので、このカメラをシーケンサーのカメラで上書きするような処理を作成します。
注意したいのが、シーケンサーでスポーンさせたカメラだとBPで呼び出せません。シーケンサーが再生されるまでそのカメラは存在していないためです。
プレイヤーのカメラ情報などを取得しているのがGet Player Controller、そのカメラを上書きするという処理をSet View Target with Blend、何で上書きするかはNew View TargetにつながっているCine Camera Actorです。Cine Camera Actorのノードはワールドアウトライナからシーケンサーで使用しているカメラを選択し、レベルブループリントにドラッグ&ドロップすると、カメラのノードがBPに作成されます。

次にシーケンサーをプレイする処理を追加します。
カメラを呼び出したあとに、シーケンサーをプレイします。ワールドアウトライナからレベルシーケンサーを選択した状態で、BPで右クリックするとシーケンサーのノードが下図のようにサジェストされます。

シーケンサーのノードが作成できたらそこから再生するという処理、Play(SequencePlayer)を設定します。シーケンサーのPlay以降にはもともとの処理をつなげておきます。

今回、シーケンサーを再生するときにプレイヤーが邪魔になってしまうので、レベルに配置しているプレイヤーはActor Hidden in Gameになっています。
この状態ではBP側はシーケンサーを再生する、という処理で終わってしまいます。シーケンサーで設定した尺を超えても、ゲーム画面には戻りません。
シーケンサー側からBPへ、シーケンサーはここで終わります、というイベントを送り、そのイベントをBP側で取得したら、ゲームを開始するという処理を繋げなければなりません。また非表示にしているプレイヤーも表示しなければいけません。
2.シーケンサーの終了を設定し、ゲーム開始の合図にする
ではシーケンサーの終了を設定してみます。
シーケンサーを開いてEventTrackを追加します。トラックが追加できたら、シーケンサーの再生を終了したい部分にキーを設定します。
キーを作成したらキー上で右クリックし、PropertiesからEvent Nameをつけておきます。ここではSeq_Endとしています。
※ここで注意したいのが、シーケンサーの尺終わりピッタリにEventTrackのキーを設定してしまうとBP側でそのキーをうまく取得できない場合があります。

作成できたらBPに移り、CustomEventを作成して、先程設定したキーの名前にします。
これにより、シーケンサーが再生され、EventTrackのキーのある位置が再生されると、キーの名前をつけたイベントがBP上で呼ばれるようになります。このイベントが呼ばれる=シーケンサーの再生が終了する、ということなので、ゲームができるようにBPのノードをつなげます。
必要なものはゲームモードの呼び出し、シーケンサーのカメラに設定したものをプレイヤーのカメラに設定し直す、プレイヤーキャラクターの表示、です。
BPは以下のようになります。上記のシーケンサーのPlayのあとにつなげていたCast to BP_RollingGameModeやOn Load Levelなどはゲーム本編に関連する処理のため、シーケンサー再生終了後に動いてほしいので、Seq_Endのイベントが起こったあとに処理されるようにつなぎ直します。
New View TargetなどにつなげているCast To BP_PhysicsBallはピュア関数というものにしておきます。ピュア関数にしておかないと実行ピンが存在してしまい、その実行ピンが繋がれていないとエラーとなってしまうためです。

ピュア関数にするには、ピュア関数にしたいノードの上で右クリック、Convert to Pure Castで行えます。

これでシーケンサーが再生し、ゲームがスタートするのですが、いくつか問題が発生します。
シーケンサーを再生している裏で、非表示にしているプレイヤーのコリジョンがぷちぷちや地面に反応して動いてしまうのです。
3.コリジョンの発生タイミングを変更する
キャラクターの初期配置を変更すれば上記の問題は解決できますが、初期位置をあまり変更したくない+スタートするまでは絶対に動いてほしくない(今回この作品はUE4のテンプレートのBallを使用しているので、球体がPhysicsで動いている=物理が効いてしまい完全に静止状態から始めることが困難)ため、コリジョンをカウントダウン後まで無効にする方法を取りました。プレイヤーのボール部分のフィジックスの設定はNo Collisionに設定しておきます。
この処理はGameModeに追加します。なぜならプレイヤーの入力を無効、受付可能のタイミングを決めているのがこのBPのためです。プレイヤーの入力を無効にしているところにコリジョンの無効を、プレイヤーの入力を受付可能にしているところにコリジョンを有効にするノードを追加します。


これでコリジョンがカウントダウン後のプレイヤーが動かせるタイミングで有効になり、シーケンサー再生中にプレイヤーが動いてしまうこともなくなりました。
4.おまけ:初回とタイトルに戻ったときのみシーケンサーが再生されるようにする
シーケンサーを再生し、無事にゲームをプレイできるようになりました。しかし、このゲームにはリトライできる機能があり、そのリトライをするたびにシーケンサーが流れていては煩わしく感じます。そこでシーケンサーを初回プレイ時と、タイトルに戻ってプレイをする時に限定し、「もう一回」を選択したときには流れないようにします。

初回プレイ時にシーケンサーを再生したか、タイトルに戻ったか、をフラグとして取得できるようにします。変数を作成して、フラグのONOFFをできるようにします。ここでは変数名をSeq_Playとします。
変数Seq_Playですが、レベルBPに作成するとレベル遷移時に読めなくなってしまいます。GameModeも同じく、パーシスタントレベルをまたいで値を保持することができません。そのため、レベルを遷移しても値を保存できるもの、が必要になります。
それを満たすのがGameInstanceです。コンテンツブラウザから右クリック→ブループリントを作成で、名前を検索して新規アセットとしてGameInstanceを作成します。

このGameInstanceには今回の使用方法としては、変数に値を保持させておくだけのため、特にBPなどは書きません。
まずシーケンサーを再生したときに、フラグが立つようにします。BPは以下のようになります。
シーケンサーを再生しているのはゲーム本編のレベルなので、そこに追加します。シーケンサーのPlayノードの後ろに、GameInstanceの呼び出しと、変数の値のセットを行います。
変数(フラグ)がONになるようにします。

そしてタイトルに戻ったときに上記とは逆の値(フラグがOFF)を変数Seq_Playにセットします。タイトルのレベルBPに以下のように追加します。

これでフラグをONOFFすることはできました。しかし、シーケンサーを再生するか、しないかの分岐をまだ追加していません。シーケンサーを再生する命令を出しているゲーム本編のレベルBPに以下のような処理を追加します。ここで変数を利用してどちらに分岐するかを決定します。上記の変数を設定している場所により、ゲームをプレイしたあとはフラグがONになっているのでその時はシーケンサーをプレイしないで、ゲームをリスタート、フラグがOFFになっているときにはシーケンサーを流してからゲームをプレイするようにします。
これで変数に入っている値を参照して、シーケンサーを再生するかどうかの分岐ができました。
長くなりましたが、BP初心者がシーケンサーをゲーム中に入れるときに躓いた点と、解決策を書かせていただきました。
参考になるものがあれば幸いです。