unityでいってみよう!

unityがチョットワカル位の人のブログ

Time.maximumDeltaTimeについて解説してみよう!

概要

「Time.maximumDeltaTimeの値を小さくしたのですが、処理落ちが改善しないのは何故ですか?」 という質問が定期的に寄せられます。 パフォーマンスに影響を与えるパラメーターという点に関してはあながち間違ってはいないのですが、1フレームにかかる実際の処理時間を制限する訳ではありません。

結論

Time.maximumDeltaTimeの値は前のフレームからの経過時間deltaTimeの上限値として使用されます。 この値はTime.timeに加算される為、Time.timeを観測している限りでは処理落ちが発生しても上限はTime.maximumDeltaTimeの値となっているように見えます。(リアル時間とは異なります) また、deltaTimeはFixedUpdateが実行される回数に影響を与える為、FixedUpdateの実行回数が減ることによりパフォーマンスの改善を行います。

解説

UnityはPlayerLoopの先頭で*1を行います。

  1. 最後のフレームからの経過時間をdeltaTimeとする
  2. deltaTimeがTime.maximumeDeltaTimeより大きい場合、deltaTimeの値をTime.maximumDeltaTimeとする。
  3. Time.timeにdeltaTimeを加算する
  4. Time.fixedTime <= Time.timeの場合、Time.fixedTimeへTime.fixedDeltaTimeを加算しFixedUpdate()を実行し、再び4を繰り返す
  5. Update()を実行する

Step2でTime.maximumeDeltaTimeを使用しています。 例えば、Time.maximumeDeltaTimeの値が0.032の場合、前のフレームに1秒かかっていたとしてもdeltaTimeは0.032となります。 仮にTime.maximumeDeltaTimeが存在しない場合のケースについて考えてみましょう。 Time.fixedTimeの値が初期値の0.02で、最後のフレームからの経過時間が1秒の場合、1 ÷ 0.02 = 50回のFixedUpdateが実行されることになります。

これは、処理落ちしてしまった時間分、Game時間(Time.time)にPhysicsの時間(Time.fixedTime)を追いつかせる為のやむなき処理なのですが、これによって1フレーム期間中に実行されるFixedUpdateの回数が増えることによって処理負荷が増加するという負のスパイラルが発生します。 その為、一定期間以上の処理落ちに関しては無かった事にしましょうというのがTime.maximumeDeltaTimeです。

GameObjectの移動にTransformにTime.deltaTimeを係数として使用するというコードを書くことがあると思いますが、大きな処理落ちが発生しTime.deltaTimeの値があまりにも大きいとワープして見えたり壁を突き抜けてしまったりというケースが想像出来ますが、Time.maximumeDeltaTimeの範囲内が最大移動距離と考える事が出来ます。この値が小さいと処理落ちした際にスローモーションで移動して見えるので、アプリ毎に良い塩梅で調整する必要があります。

つまり処理落ちした際の移動制限をユーザー側が独自にやっている場合はPhysicsとの整合性が取れなくなる可能性がある為注意が必要です独自にやるのではなく、Time.maximumeDeltaTimeで制限をかけることでアプリ全体で整合性を取る方が良いでしょう。

もしアプリケーションの1フレームにかかる処理時間をTime.deltaTimeで計測しているのであればそれは間違いです。上記で述べた通りTime.deltaTimeはTime.maximumeDeltaTimeでキャップされている為、実際にかかった処理時間を返しません。1フレームに掛った処理時間を求めるのであればTime.unscaledDeltaTimeを使用する必要があります。

まとめ

  • Unityは処理落ちが発生した場合、実際にかかった時間分処理をすすめようとしますが、そこに制限をかけるのがTime.maximumeDeltaTimeです。
  • 処理落ちが発生してもTime.maximumeDeltaTime以上アプリ内時間が進むことはありません。
  • 処理落ちが発生した場合、落ちた時間の長さに応じてFixedUpdateが実行される回数が増える為、さらに処理負荷が増加するが処理落ち時間を制限することによってFixedUpdateの回数を抑えることが可能です。
  • FixedUpdateが複数回実行されることによる処理落ちを改善する効果は期待できます。

関連記事

unityletsgo.hatenablog.com

*1:下記の処理