本日は Unity の小ネタ枠です。
今回は TimeScale を使ってシーンの再生速度を変えた時、Unity 内の時間経過と実際の時間経過を計測する方法についてです。
前回記事
前回記事の続きです。
シーンの再生速度を変更する方法については以下の記事を参照ください。
bluebirdofoz.hatenablog.com
Unscaled
Unity 内の経過時間を取得する Time.time や前回フレームからの経過時間を取得する Time.deltaTime は TimeScale の影響を受けます。
TimeScale の影響を受けない実際の経過時間を取得したい場合は Time.unscaledTime や Time.unscaledDeltaTime を参照します。
docs.unity3d.com
動作確認
Time.deltaTime と Time.unscaledDeltaTime を使ってフレームごとに経過時間を計測するサンプルスクリプトを作成しました。
・UnscaledTest.cs
using UnityEngine; public class UnscaledTest : MonoBehaviour { private float totalDeltaTime; private float unscaledTotalDeltaTime; void Start() { // 時間の進みを2分の1の速度にする Time.timeScale = 0.5f; } void Update() { // 初回フレームはシーンがアクティブになるまでの経過時間を含んでしまうため、加算に含めない if (Time.frameCount == 1) { totalDeltaTime = 0.0f; unscaledTotalDeltaTime = 0.0f; Debug.Log($"シーン内の経過時間:{totalDeltaTime}、現実の経過時間:{unscaledTotalDeltaTime}"); return; } totalDeltaTime += Time.deltaTime; unscaledTotalDeltaTime += Time.unscaledDeltaTime; Debug.Log($"シーン内の経過時間:{totalDeltaTime}、現実の経過時間:{unscaledTotalDeltaTime}"); } }
シーンを再生すると以下の通り、unscaled の方は現実の経過時間が表示されます。
unscaledの注意点
unscaled の経過時間はアプリが非アクティブの状態(ウィンドウの最小化など)でも進むため、必ずしも TimeScale に比例した値にならない点に注意が必要です。
また計測の開始タイミングも異なるようで例えば以下のようなスクリプトを試すと、初回フレームの経過時間が大きく変化しました。
・UnscaledTest2.cs
using UnityEngine; public class UnscaledTest2 : MonoBehaviour { private float totalDeltaTime; private float unscaledTotalDeltaTime; void Start() { // 時間の進みを2分の1の速度にする Time.timeScale = 0.5f; } void Update() { // 初回フレームの経過時間を確認する if (Time.frameCount == 1) { totalDeltaTime += Time.deltaTime; unscaledTotalDeltaTime += Time.unscaledDeltaTime; Debug.Log($"シーン内の経過時間:{totalDeltaTime}、現実の経過時間:{unscaledTotalDeltaTime}"); return; } } }