[Unity] Time.timeとTime.realtimeSinceStartupについてのお話
Unityでモーションを実現したいとき、現在時刻を参照することはよくあると思われます。
現在時刻はTime.timeから分かります。
しかし、このTime.timeはTime.timeScaleの値により時刻の進行速度が変化します。
デフォルトはTime.timeScale=1となっており、本来の速度で時間が経過していきます。
Time.timeScaleの値によらない時刻を取得するには、Time.realtimeSinceStartupを参照します。
したがって、Time.timeScale=1のとき、Time.timeとTime.realtimeSinceStartupは同じ値になると考えられます。
しかし、実際に値を取得すると微妙に異なっていることが分かります。
以下がその検証用スクリプトです。
using UnityEngine; using System.Collections; public class TimeTest : MonoBehaviour { // Use this for initialization void Start () { } // Update is called once per frame void Update () { Debug.Log ("Time.time = " + Time.time + " , Time.realtimeSinceStartup = " + Time.realtimeSinceStartup); } }
実際に結果をコンソールに出力してみると、見事に値が異なっていることを確認できます。
Time.time = 6.569162 , Time.realtimeSinceStartup = 6.58668 Time.time = 6.591497 , Time.realtimeSinceStartup = 6.609009 Time.time = 6.593105 , Time.realtimeSinceStartup = 6.610617 Time.time = 6.594737 , Time.realtimeSinceStartup = 6.612248
※2014/12/13 追記
しかし、上記のコードではTime.timeの参照後にTime.realtimeSinceStartupを参照しているので結果として値がずれて当然かと思われます。
試しに以下のように順序を入れ替えて実行してみます。
using UnityEngine; using System.Collections; public class TimeTest : MonoBehaviour { // Use this for initialization void Start() { } // Update is called once per frame void Update() { Debug.Log("Time.realtimeSinceStartup = " + Time.realtimeSinceStartup + " , Time.time = " + Time.time); } }
Time.realtimeSinceStartup = 0.6573095 , Time.time = 0.6098088 Time.realtimeSinceStartup = 0.6772348 , Time.time = 0.6300333 Time.realtimeSinceStartup = 0.6972438 , Time.time = 0.6509956 Time.realtimeSinceStartup = 0.7172379 , Time.time = 0.6701386
Time.realtimeSinceStartupを先に参照しているにもかかわらずTime.timeより値が大きくなっています。
両者ともゲーム起動時からの経過時間ですが、Time.realtimeSinceStartupはリアルタイムな時間、Time.timeは現在フレームの開始時における時間となり内容が異なります。
Time.timeがTime.realtimeSinceStartupより小さかったのはこのためです。
同フレームの中で両者を2回ずつ参照してみます。
using UnityEngine; using System.Collections; public class TimeTest : MonoBehaviour { // Use this for initialization void Start() { } // Update is called once per frame void Update() { Debug.Log( "Time.realtimeSinceStartup:1 = " + Time.realtimeSinceStartup + " , Time.realtimeSinceStartup:2 = " + Time.realtimeSinceStartup + " , Time.time:1 = " + Time.time + " , Time.time:2 = " + Time.time); } }
Time.realtimeSinceStartup:1 = 3.114911 , Time.realtimeSinceStartup:2 = 3.114912 , Time.time:1 = 3.083903 , Time.time:2 = 3.083903 Time.realtimeSinceStartup:1 = 3.131449 , Time.realtimeSinceStartup:2 = 3.13145 , Time.time:1 = 3.100469 , Time.time:2 = 3.100469 Time.realtimeSinceStartup:1 = 3.147841 , Time.realtimeSinceStartup:2 = 3.147842 , Time.time:1 = 3.117036 , Time.time:2 = 3.117036 Time.realtimeSinceStartup:1 = 3.164524 , Time.realtimeSinceStartup:2 = 3.164525 , Time.time:1 = 3.133603 , Time.time:2 = 3.133603
Time.realtimeSinceStartupは同フレームでの1回目と2回目の値が異なりタイマーが進行していることが分かります。
一方でTime.timeは1、2回目とも同じ値です。
同フレーム内ではTime.timeは固定の値となります。
このことからも、両者のタイマー値を混在して使うのはバグの元になると断言できます。
勿論、両者の値の意味を知った上で併用するのは問題ありません。
タイマーを使うときはどちらを使うかを慎重に選ぶ必要があります。
Time.timeとTime.realtimeSinceStartupを同じ意味の値として比較すれば時間が逆戻りしたりして大変なことになります。
(ここで私はド嵌りしました・・・)
今回はタイマーの使用上の注意点ということで挙げておきました。
■参考サイト
Unity – Scripting API: Time.realtimeSinceStartup
Unity – Scripting API: Time.time
COMMENTS & TRACKBACKS
- Comments ( 2 )
- Trackbacks ( 0 )
同時に呼び出してるわけではないので必ずしも同じ値にならないのではないでしょうか
ご指摘ありがとうございます。
記事の検証用スクリプトだけでは誤解を招いてしまう内容でしたので、追記しておきました。
Time.timeとTime.realtimeSinceStartupには厳密に同時にアクセスできないので、アクセス時間のずれが生じます。
同フレーム内でTime.realtimeSinceStartupに続けざまにアクセスすると時間が進行して値が大きくなります。
一方、Time.timeは現在フレームが開始したときの時間なので、Time.realtimeSinceStartup→Time.timeの順にアクセスしてもTime.timeのほうが値が小さくなります。
(Time.timeScaleを変更しなくともTime.timeよりTime.realtimeSinceStartupの方が時間進行している)
同フレーム内でTime.timeに何回アクセスしても値は変わりません。
このことについて追記にまとめたので参考にしていただければと思います。