一定時間ごとに状態を切り替えたり、N秒後に何かを起こしたりするには、Time クラスを使って経過時間を管理します。このページでは経過時間(duration)の概念と、それをフィールドで管理する方法を学びます。
このページを読み終えると、以下のことができるようになります。
Time.time でゲーム開始からの経過時間を取得できるTime.deltaTime を組み合わせて duration を管理できるTime.time がゲーム時間であり現実時間とは異なることを説明できるTime クラスは Unity の時間管理を担うクラスです。このページでは以下の3つのプロパティを扱います。
| プロパティ | 説明 | 既習 |
|---|---|---|
Time.deltaTime |
前のフレームからの経過時間(秒) | ✅ |
Time.time |
ゲーム開始からの累計経過時間(秒) | このページ |
Time.timeScale |
時間の流れる速さのスケール(既定値 1.0) |
このページ |
Time.time — ゲームが開始されてからの累計経過時間(秒)を返します。
書式:Time.time プロパティ
1
public static float time { get; }
Time.time はゲーム開始時を 0 として毎フレーム増え続けます。「あの時点から何秒経ったか」を計測するには、開始時刻をフィールドに記録しておき差し引きます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using UnityEngine;
public class TimeSample : MonoBehaviour
{
private float _startTime;
private void Start()
{
_startTime = Time.time; // 開始時刻を記録
}
private void Update()
{
float elapsed = Time.time - _startTime;
Debug.Log($"経過時間: {elapsed:F1} 秒");
}
}
elapsed は毎フレーム「現在の時刻 − 開始時刻」を計算するため、Start が呼ばれてからの経過秒数が得られます。
Time.deltaTime をフィールドに積算し、しきい値を超えたら状態を反転させることで、一定間隔の繰り返し処理を作れます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
using UnityEngine;
public class Blinker : MonoBehaviour
{
[SerializeField] private float _interval = 0.5f; // 切り替え間隔(秒)
private float _timer = 0f;
private bool _isOn = true;
private void Update()
{
_timer += Time.deltaTime;
if (_timer >= _interval)
{
_timer -= _interval; // リセットではなく差し引いて超過分を次へ持ち越す
_isOn = !_isOn;
Debug.Log(_isOn ? "ON" : "OFF");
}
}
}
_timer = 0 ではなく _timer -= _interval とすることで、フレームの長さによる超過分が次のサイクルに持ち越されます。長時間動かしてもタイミングのズレが蓄積しません。
💡 ポイント:
Debug.Logの行をGetComponent<Renderer>().enabled = _isOn;に置き換えると、オブジェクトの表示・非表示を一定間隔で切り替える点滅エフェクトになります。
Time.time はゲーム時間です。現実の時計とは異なり、Time.timeScale の値によって速さが変わります。
Time.timeScale — 時間の流れる速さのスケールを設定・取得します。
書式:Time.timeScale プロパティ
1
public static float timeScale { get; set; }
| 値 | 効果 |
|---|---|
1.0(既定値) |
現実と同じ速さ |
0.5 |
スローモーション(半速) |
2.0 |
倍速 |
0.0 |
ゲームポーズ(時間が止まる) |
前のセクションで作った Blinker に [SerializeField] で _timeScale を持たせると、Inspector から値を変えるだけで点滅速度が変化することを確認できます。
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
using UnityEngine;
public class Blinker : MonoBehaviour
{
[SerializeField] private float _interval = 0.5f;
[SerializeField] private float _timeScale = 1.0f; // Inspector から変更できる
private float _timer = 0f;
private bool _isOn = true;
private void Start()
{
Time.timeScale = _timeScale;
}
private void Update()
{
_timer += Time.deltaTime;
if (_timer >= _interval)
{
_timer -= _interval;
_isOn = !_isOn;
Debug.Log(_isOn ? "ON" : "OFF");
}
}
}
_timeScale を変えると Time.deltaTime の値が変わるため、_timer の積算速度が変化します。
Inspector の _timeScale |
Time.deltaTime の変化 |
現実時間での切り替わり |
|---|---|---|
0.5 |
半分になる | 1.0 秒ごと(遅い) |
1.0 |
そのまま | 0.5 秒ごと(通常) |
2.0 |
2倍になる | 0.25 秒ごと(速い) |
0.0 |
0 になる |
切り替わらない(停止) |
💡 ポイント: 現実時間(システムクロック)を扱いたい場合は、C# 標準ライブラリの
DateTime・DateTimeOffsetを使います。詳しくは 補足: 現実時間の取得(DateTime と DateTimeOffset) を参照してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
// ❌ NG: _timer = 0 でリセットすると超過分が捨てられ、長時間でズレが蓄積する
if (_timer >= _interval)
{
_timer = 0;
_isOn = !_isOn;
}
// ✅ OK: 超過分を差し引いて次のサイクルに持ち越す
if (_timer >= _interval)
{
_timer -= _interval;
_isOn = !_isOn;
}
Time.time はゲーム開始からの累計経過時間(ゲーム時間)Time.time - _startTime で経過時間を計算できるTime.deltaTime をフィールドに積算してしきい値で処理するパターンで一定間隔の繰り返しを作れる_timer -= _interval で超過分を持ち越すとズレが生じないTime.timeScale でゲーム時間の速さを制御できる(0 でポーズ、Time.deltaTime が 0 になりタイマーが止まる)以下の問いに答えられるか確認しましょう。
Time.time と Time.deltaTime の違いを説明してください。Time.timeScale = 0 にしたとき、Time.deltaTime ベースのタイマーはどうなりますか?次のコードは何秒ごとに状態を切り替えますか?
1
2
3
4
5
6
7
8
9
10
11
12
[SerializeField] private float _interval = 1.5f;
private float _timer = 0f;
private void Update()
{
_timer += Time.deltaTime;
if (_timer >= _interval)
{
_timer -= _interval;
// 状態を切り替える処理
}
}
Time.time はゲーム開始時を 0 とした累計経過時間。Time.deltaTime は前のフレームから今のフレームまでの短い経過時間。Time.deltaTime が 0 になるため、_timer の積算が止まりタイマーが自動的にポーズされる。_interval = 1.5f なので、1.5秒ごとに切り替わる。チュートリアル: 信号機 では、Update と Time を組み合わせたステートマシンパターンを総合演習として実装します。