ほげたつブログ

プログラムとアニメーションをかじって生きてる

UE4 - ポーズ対応まとめ

こちらは「UE4 Advent Calendar 其の弐」5日目の記事です。

Unreal Engine 4 (UE4) 其の弐 Advent Calendar 2015 - Qiita

今回のお題は「ポーズ対応周りについて」です。

UE4 におけるポーズ機能の対応状況について

UE4 ではエンジン全体でポーズ機能をサポートしています。

任意のプロジェクトを作成し、ゲームの再生を開始して「Pause」キーを押してみてください。
レベルに存在するアクターが静止したかと思います。

こちらは「一時停止デバッグメニュー」で、Developmentビルドではデフォルトで有効になっています。
この辺りは既に記事にしてあるので、そちらをご覧下さい。

hogetatu.hatenablog.com


デバッグ用途のシンプルなポーズであれば、これをそのまま使っても問題ないかと思います。

インゲーム用にUI表示付きのポーズを作る

説明用にPauseキーでトグルするポーズ機能を作ってみます。


まず、事前処理として上記の記事を参考にデバッグ用のポーズ機能を無効化し、InputAction に「Pause」を追加しておいて下さい。


ポーズ機能は特定のレベルに紐付くものではないので、ここでは PlayerController に処理を記述します。
コントローラー初期化時にポーズ中にオーバーレイ表示するUI(PauseMenu)を作って変数に入れておきます。

f:id:hogetatu:20151203021732p:plain


次に、ポーズ状態をトグルするためのイベントを追加します。
「Set Game Paused」ノードを使うことでポーズ機能のON/OFFが切り替えられます。

f:id:hogetatu:20151203015742p:plain


最後に、ポーズトグルイベントを呼び出すためのキーイベントを追加します。

f:id:hogetatu:20151203022531p:plain


ここで一つ注意したいことがあります。
ポーズ切り替えのための InputAction を拾うイベントですが、「Execute when Paused」プロパティを有効にしてあげる 必要があります。
ポーズ中は各種イベントも発生しなくなるため、これを怠るとポーズ状態にした後、キー入力が取れずにポーズが解除できないといった事になりますのでご注意ください。


これでPauseキーを押すことでポーズ状態を切り替えられるようになりました。

f:id:hogetatu:20151203022539p:plain


ポーズ中に止まるものについて

ポーズ中はアニメーションはもちろん、物理やパーティクル等の更新も止まります。
以下、少し特殊な動作をするものについての補足です。

EventTick

EventTick も実行されなくなりますが、もしポーズ中にも EventTick を有効にしたいアクターがあった場合は、アクターの「Class Defaults」から「Actor」カテゴリ内の「Tick Even when Paused」プロパティを有効にして下さい。
ほとんどのアクターは「Tick Even when Paused」がデフォルトで無効になっていますが、PlayerController 等のデフォルトで有効になっているものもありますので注意してください。

InputAction

Pauseキーイベントでも触れましたが、ポーズ中は InputAction は実行されなくなります。
ポーズ中も実行したい場合は、イベントを選択して「Execute when Paused」プロパティを有効にして下さい。

InputAxis

こちらは InputAction と違い、「Execute when Paused」プロパティを無効にしても実行されます
ただバグなのかといえばそうではなく、プロパティが無効の場合は AxisValue が 0 になる仕様のようです。

UMG(UserWidget)

UserWidgetはアクターではありません。
そのため、「Tick Event when Paused」プロパティが存在しません。(思想的にそうなのか、単純に未対応なのかはわかりません)
だからポーズ中であっても EventTick は呼ばれ続けますし、カットイン等のアニメーションの再生も止まりません。

自分も自作ゲームでこれに遭遇して困りましたが、仕方なくC++で UserWidget を継承したクラスを用意して対応しました。
PauseUserWidget という名前のクラスで、アクターと同じように「Tick Even when Paused」プロパティが用意されています。

処理内容自体はとても簡単なもので、EventTick を呼び出したりアニメーションの更新を行っている NativeTick 関数をオーバーライドして、新設した「Tick Even when Paused」プロパティを参照して更新するかどうかを判断しているだけです。

上記クラスをプロジェクトに定義し、通常通り UserWidget を作成後、「Class Settings」から「Class Options」カテゴリ内の「Parent Class」を PauseUserWidget に変更して下さい。

サンプルプロジェクト

GitHub にポーズ確認用のサンプルプロジェクトを作成しました。
UE4.9.2 に対応しています。

github.com

clone もしくは Download Zip し、uproject を右クリックして「Generate Visual Studio project files」し、生成された sln を VS2013 で開いてビルドして実行して下さい。

ソースコードビルドに関する解説は割愛します。

動画

youtu.be


明日のアドカレ

明日(6日目)は com04 さんによる「24時間チャレンジ!1から出来るとこまでセルシェード」です。
テーマだけで面白そうなので超期待です。