UE4でTick実行依存関係の設定とポーズ中のTick実行を併用すると問題が起こる
8月でようやく仕事が少しだけ落ち着いたので少しずつ更新頻度を上げていこうと思います。
こちらの記事内で Add Tick Prerequisite Actor / Component を使って複数の Tick 間に依存関係を持たせ、実行順を制御する方法について書きましたが、ポーズ中は依存関係を無視して実行する という地雷を踏んだので備忘録として残しておきます。
検証
過去記事と同じような内容になりますが、下記の環境で検証を行います。
レベルに配置するテストアクターのイベントグラフ
BeginPlay でプロパティから指定されたアクターに対して Add Tick Prerequisite Actor で依存関係を設定しています。Tick ではアクター名を画面に出力するだけの単純な BP です。アクターのクラスデフォルト設定から Tick Even when Paused にチェックを入れてポーズ中にも Tick が実行されるようにしておきます。
レベル BP のイベントグラフ
Tick でポーズ状態を画面に出力し、Enterキーを押されたらポーズ状態をトグルするだけの単純な BP です。こちらもクラスデフォルト設定から Tick Even when Paused にチェックを入れてポーズ中にも Tick が実行されるようにしておきます。
レベルにテストアクターを配置
テストアクターを複数個配置して、BP_Test1 に BP_Test2 を依存させる、BP_Test2 に BP_Test3 を依存させる、といった感じで上から依存関係を設定していきます。
非ポーズ時(通常状態)の実行結果
これは過去記事での検証結果と同じで、Tickの実行順序が問題なく制御できていることが確認できます。
ポーズ時の実行結果
Enter を押してポーズ状態に切り替えると実行結果が変わります。Tick の依存関係を設定しているにも関わらず、意図した順番で Tick が実行されていません。
まとめ
今回はアクター間の Tick に依存関係を持たせて実験しましたが、これが単一アクターにぶら下がる複数のコンポーネント間で依存関係を持たせていた場合に結構厄介です。筆者は Skeletal Mesh Component の Tick でアニメーションポーズを決定し、その後に他のコンポーネントから骨物理を更新するというフローを組んでいましたが、ポーズ中にキャラをアニメーションさせようとした時に骨物理が動かないことがあるというバグを踏みました。FTickTaskLevel::RunPauseFrame を眺めている限りだとポーズ中は TickFunction の登録順で実行されるようなので、正常に動くときと動かない時が混在するのが微妙に厄介ですね。