Unityでの時間の扱い方を解説します。今回解説するのは3つ!
Time、Coroutine、StopWatchです。それぞれの特徴は以下の通り。
Time:Unity内で前フレームから経過した時間を取得する
Coroutine:一定時間おきに処理に向いている
StopWatch:Unityのシーン内ではなく、スクリプト上で経過時間を計測できる(処理にかかる時間を計測できる、開発用)
以上3つの中で1つでも知らないものがある方は、この記事を読む価値があります。3つ覚えておくと、使いわけることでスクリプトが楽にかけるようになりますよ。
それぞれの解説は、特徴の説明→コード→具体例の流れで行います。
Timeの使い方
まず初めにTimeの使い方を解説します。Timeはもっとも簡単に実装できるのでまずはTimeの使い方を覚えておくことをおすすめします。
ぶっちゃけるとTimeが使えればだいたい時間の処理は代用できます。
Unityで時間を計測したい人が主だと思うので、以下ではTimeを用いて、経過時間をコンソール上へ出力するコードを解説します。
・Timeの説明
Timeは、フレームごとの時間を計測し格納します。今回紹介するのは以下2つ。
Time.time:シーン開始から経過した時間
Time.deltaTime:最後のフレームを完了するのに要した時間(フレーム毎の時間)
他にもTimeを取得できるインターフェースは多々ありますが、この2つを使えれば十分でしょう。
興味のある方は下記リンクから詳細を確認できます。
・経過時間の計測用コード
Time.timeを使ってゲーム開始からの経過時間を取得するコード
1 2 3 4 5 6 7 8 9 |
using UnityEngine; public class TimeScript : MonoBehaviour { void Update() { Debug.Log(Time.time); } } |
Time.deltaTimeを使用して計測開始、停止を自分で決められるコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
using UnityEngine; public class TimerScript : MonoBehaviour { float elapsedTime; bool counter_flag = false; void Update() { //Spaceキーで計測開始、停止を切り替え if (Input.GetKey(KeyCode.Space)) { counter_flag = !counter_flag; } if (counter_flag == true) { elapsedTime += Time.deltaTime; Debug.Log("計測中: " + (elapsedTime).ToString()); } } } |
・Unity上で動かしてみる
Time.timeで経過時間を出力した結果は以下の通り。
Time.timeはゲーム開始から経過した時間を簡単に出力できます。ただし、読み取り専用のため、以下のように値を代入することはできません。
つまり、Time.timeは計測するスタート位置を指定できないというデメリットがあります。
1 2 |
//読み取り専用のため、代入できない Time.time = 10f; |
ちなみに残り時間を計測したいなら、60f – Time.timeのように実装できますね。
Time.deltaTimeで計測開始、計測停止位置を指定できるコードを動かすと以下のようになります。
Spaceキーを1回押すと測定開始、2回目に測定を終了します。
Time.deltaTimeは最後のフレームにかかった時間を読み込めます。つまり、Update()内に elapsedTime += Time.deltaTimeのように足し合わせていくことでタイマーのように経過時間を計測することができます。
Time.deltaTimeはゲームを開始した時間に依存しないので、このように計測位置を自由に変更できるのが強みです。
ある特定の処理時に時間を計測する際は、Time.deltaTimeを格納した変数を初期化するだけで、再度時間の計測が行えます。
Coroutineの使い方
Coroutine(コルーチン)は一定の時間を空けて処理を行いたい際に便利です。
処理A→X秒待機→処理B→Y秒待機→処理C→・・・のように異なる処理を待機時間を指定して実行できます。
・Coroutineの説明
先にも書いた通り、Coroutineは一定の時間を空けて処理を行う際に便利です。
これを言い換えると、Coroutineは処理を中断・再開することが自由にできるということです。
マリオブラザーズでいうキラー大砲のようなイメージですね。一定時間の間を空けてキラーを飛ばす処理はCoroutineに近いと思います。
・一定時間おきに処理を行うコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
using UnityEngine; public class CoroutineScript : MonoBehaviour { void Start() { StartCoroutine("Coroutine"); } private IEnumerator Coroutine() { //処理1 Debug.Log("Start"); //1秒待機 yield return new WaitForSeconds(1.0f); //処理2 Debug.Log("1秒経過"); //4秒待機 yield return new WaitForSeconds(4.0f); //処理3 Debug.Log("5秒経過"); //コルーチンを終了 yield break; } } |
処理1→1秒待機→処理2→4秒待機→処理3のように処理を行います。
待ち時間は以下のように記述できます。1.0の数値を変えるだけですね。
1 |
yield return new WaitForSeconds(1.0f); |
コルーチンを途中で終了したい場合は以下のコード。
1 |
yield break; |
・Unity上で動かしてみる
UnityでCoroutineのスクリプトを動かした結果です。
スクリプトどおりに5秒経過を出力しています。
コルーチンは以上のように処理を中断・再開できるのが最大の強みです。
さらに詳しくコルーチンについてしりたい方は以下の記事が参考になります。
StopWatchの使い方
最後はStopWatchです。
これはスクリプト内の処理にかかる時間を計測する際に使えます。
・StopWatchの説明
StopWatchはUnity上の処理にかかる時間ではなく、スクリプト内で処理にかかる時間を計測します。そのため、Unity上で時間を計測するのではなく、開発時に処理の負荷を調べるために便利かと思います。
StopWatchはStart, Stop, Elapsedなど単純なメソッドの呼び出しで操作できるため、使い勝手がいいのも魅力です。
・スクリプト内の処理時間を出力するコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
using UnityEngine; using System; public class StopWatchScript : MonoBehaviour { int a = 0; void Update() { if (Input.GetKey(KeyCode.A)) { //StopWatchを定義 var sw = new System.Diagnostics.Stopwatch(); sw.Start(); //計測開始 //時間計測したい処理 for(int i = 0; i < 1000000f; i++) { a += i; } Debug.Log(sw.Elapsed); //経過時間 sw.Stop(); //計測終了 } } } |
using System;を宣言しないと使えないので要注意です。
時間計測したい処理をStartとStopではさんであげるだけで、処理にかかる時間を計測できます。
その他コマンドは以下の通り。
1 2 |
sw.Elapsed : Start-Stop間の経過時間 sw.Restart(): 経過時間をリセットして再計測開始 |
・スクリプトの処理時間を計測してみる
sw.Elapsedは時間:分:秒.の形式で出力されます。
単位ごとにそれぞれ以下のように記述することで取り出せます。
1 2 3 4 |
sw.Elapsed.Hours //時間 sw.Elapsed.Minutes //分 sw.Elapsed.Seconds //秒 sw.Elapsed.Milliseconds //ミリ秒 |
00:00:00:00.0026832の場合は2ミリ秒として出力されますね。
以上でUnityで時間を扱う方法の解説は終わりです。今回紹介した3つはどれも長所と短所があるので使い分けることで時間を思い通りに扱えるかと思います。
最後まで読んでいただきありがとうございました。