フレーム/秒 (FPS) 単位での所定のフレームレートでは、個々のフレームの継続時間が異なる傾向があります。これらは軽微な変動である可能性があります。例えば、60 FPS で実行されているゲームで、1 秒あたりの実際のフレーム数が若干異なる場合があります。この場合、各フレームは 0.016 秒 - 0.018 秒継続します。アプリケーションが負荷の高い計算やガベージコレクションを実行する場合や、他のアプリケーションとのリソースの競合が発生した場合は、より大きな変動が発生する可能性があります。
Time.time は、アプリケーションの開始から経過した時間を示すため、通常は継続的かつ着実に増加します。Time.deltaTime は、最後のフレームからの経過時間を示すため、理想的にはほとんど一定に保たれます。これらの値はどちらも、リアルタイムではなくゲーム内の時間 に基づいています。つまり、適用した時間のスケーリングが反映されます。例えば、スローモーション効果を得ようと Time.timeScale を 0.1 に設定すると、Time.time の値はリアルタイムの 10% のレートで増加します。リアルタイムで 10 秒過ぎると、Time.time の値は 1 増加します。
ゲーム内の時間を遅くしたり早めたりするだけでなく、Time.timeScale を 0 に設定してゲームを一時停止できます。この場合も Unity は Update メソッドを呼び出しますが、Time.time はまったく増加せず、Time.deltaTime は 0 です。
これらの値も Time.maximumDeltaTime の値で制限されます。これらのプロパティによってレポートされる一時停止の長さやフレームレートの変動は、Time.maximumDeltaTime を超えることはありません。例えば、1 秒の遅延が発生しても、maximumDeltaTime がデフォルト値の 0.333 に設定されている場合、現実世界では 1 秒経過しているにもかかわらず、Time.time は 0.333 増加するだけで、Time.deltaTime は 0.333 と等しくなります。
これらの各プロパティのスケールされていないバージョン (Time.unscaledTime、Time.unscaledDeltaTime) は、これらの制限を無視し、どちらの場合でも実際の経過時間をレポートします。これは、ゲームがスローモーションで再生されているときでも、決まったスピードで反応する必要があるすべてのものに役立ちます。この例としては、UI インタラクションアニメーションがあります。
下表は、16 のフレームが次々に流れ、中間に位置する 1 つのフレームで大きな遅延が発生する例を示しています。これらの数値は、さまざまな Time クラスのプロパティが、フレームレートのこの大きな変動をどのようにレポートし応答するかを示しています。
| フレーム | unscaledTime | time | unscaledDeltaTime | deltaTime | smoothDeltaTime |
|---|---|---|---|---|---|
| 1 | 0.000 | 0.000 | 0.018 | 0.018 | 0.018 |
| 2 | 0.018 | 0.018 | 0.018 | 0.018 | 0.018 |
| 3 | 0.036 | 0.036 | 0.018 | 0.018 | 0.018 |
| 4 | 0.054 | 0.054 | 0.018 | 0.018 | 0.018 |
| 5 | 0.071 | 0.071 | 0.017 | 0.017 | 0.018 |
| 6 | 0.089 | 0.089 | 0.018 | 0.018 | 0.018 |
| 7 | 0.107 | 0.107 | 0.018 | 0.018 | 0.018 |
| 8 (a) | 1.123 (b) | 0.440 (c) | 1.016 (d) | 0.333 (e) | 0.081 (f) |
| 9 | 1.140 | 0.457 | 0.017 | 0.017 | 0.066 |
| 10 | 1.157 | 0.474 | 0.017 | 0.017 | 0.056 |
| 11 | 1.175 | 0.492 | 0.018 | 0.018 | 0.049 |
| 12 | 1.193 | 0.510 | 0.018 | 0.018 | 0.042 |
| 13 | 1.211 | 0.528 | 0.018 | 0.018 | 0.038 |
| 14 | 1.229 | 0.546 | 0.018 | 0.018 | 0.034 |
| 15 | 1.247 | 0.564 | 0.018 | 0.018 | 0.031 |
| 16 | 1.265 | 0.582 | 0.018 | 0.018 | 0.028 |
フレーム 1 - 7 は、1 秒あたり約 60 フレームの安定した速度で流れています。Time.time と Time.unscaledTime の両方がともに着実に増加しており、Time.timeScale が 1 に設定されていることがわかります。
フレーム 8 (a) で、1 秒を超える大きな遅延が発生します。これは、リソース競合が発生した場合に発生する可能性があります。例えば、ある操作がメインプロセスをブロックし、その間にディスクから大量のデータをロードする場合などです。
フレームの遅延が Time.maximumDeltaTime を超えると、Unity は Time.deltaTime からレポートされる値と、Time.time に追加される値を制限します。これにより、時間ステップがその値を超えた場合に発生する可能性のある望ましくない副作用を回避します。この制限がないと、Time.deltaTime によって移動がスケールされるオブジェクトは、理論的に、あるフレームから次のフレームまで無制限の距離を移動できてしまいます。これは、例えば、キャラクターが壁などの障害物を妨げられることなく通り抜けるような、異常な効果を引き起こす可能性があります。
Time.maximumDeltaTime を調整するには、エディターで Time ウィンドウの Maximum allowed timestep 設定を変更するか、コードで Time.maximumDeltaTime プロパティの値を設定します。
デフォルトの Time.maximumDeltaTime 値は 1/3 (0.3333333) 秒です。つまり、Time.deltaTime が移動を制御するゲームでは、あるフレームから次のフレームへのオブジェクトの移動は、直前のフレームから実際に経過した時間は関係なく、1/3 秒で移動できる距離に制限されます。
上表のデータをグラフ形式で見ると、これらの時間のプロパティが互いにどのように作用するかを視覚化するのに役立ちます。
フレーム 8 では、Time.unscaledDeltaTime (d) と Time.deltaTime (e) でレポートされる経過時間が異なります。リアルタイムではフレーム 7 と 8 の間に 1 秒の経過時間がありますが、Time.deltaTime では 0.333 秒しかレポートされていません。これは、Time.deltaTime が Time.maximumDeltaTime の値に制限されるためです。
同様に、Time.unscaledTime (b) は実際 (上限なし) の値が追加されているため約 1 秒増加していますが、Time.time (c) は小さい上限値分だけ増加しています。Time.time は経過したリアルタイムに追いつくことができず、代わりに、遅延の継続時間が Time.maximumDeltaTime であったかのように動作します。
Time.smoothDeltaTime プロパティは、アルゴリズムに従ってスムージングされたすべての変動による最近の Time.deltaTime 値の近似をレポートします。これは、動きやその他の時間ベースの計算の望ましくない変動を回避するためのもう 1 つのテクニックです。特に、Time.maximumDeltaTime で設定されたしきい値を下回る場合のテクニックです。スムージングアルゴリズムは、将来の変動を予測することはできませんが、最近経過した Time.deltaTime 値の変動を滑らかにするために、レポートされた値を徐々に適応させ、レポートされた平均時間が実際の経過時間とほぼ同じになるようにします。
maximumDeltaTime 値は、固定更新ループ にも影響します。物理演算システムは、Time.fixedDeltaTime で定義された固定時間間隔を使用して、各ステップでシミュレートする時間を決定します。Unity は、経過した時間に応じて物理演算シミュレーションを最新の状態に維持しようとし、フレームごとに複数の物理演算更新を実行する場合があります。
ただし、物理演算シミュレーションが遅れすぎると、現在の時間に追いつくために、物理演算システムで多くのステップが必要になる場合があります。これらの追いつくためのステップ自体が、さらに速度低下する原因となる場合があります。速度低下のフィードバックループを回避するために、Time.maximumDeltaTime 値は物理演算システムが任意の 2 つのフレーム間でシミュレートする時間の制限としても機能します。
フレーム更新処理時間が Time.maximumDeltaTime を超える場合、物理演算エンジンは追加の時間のシミュレーションを行わず、代わりにフレーム処理が追いつけるようにします。フレーム更新が完了すると、物理演算は、停止してからまったく時間が経過していないかのように再開します。
この結果、物理演算オブジェクトは通常のようにリアルタイムで完全には動かず、わずかに減速します。ただし、物理演算システムは、それが正常に動いているかのように追跡します。物理演算時間の遅延は通常は目立たず、ゲームパフォーマンスとの許容範囲の妥協策です。
以下のフローチャートは、Unity が 1 つのフレーム内の時間をカウントするために使用するロジックと、time、deltaTime、fixedDeltaTime、maximumDeltaTime プロパティがどのように相互に関係しているかを示しています。