Unity & C# 学習教材

Time クラスと時間制御

一定時間ごとに状態を切り替えたり、N秒後に何かを起こしたりするには、Time クラスを使って経過時間を管理します。このページでは経過時間(duration)の概念と、それをフィールドで管理する方法を学びます。

学習目標

このページを読み終えると、以下のことができるようになります。

前提知識


1. Time クラスの主なプロパティ

Time クラスは Unity の時間管理を担うクラスです。このページでは以下の3つのプロパティを扱います。

プロパティ 説明 既習
Time.deltaTime 前のフレームからの経過時間(秒)
Time.time ゲーム開始からの累計経過時間(秒) このページ
Time.timeScale 時間の流れる速さのスケール(既定値 1.0 このページ

2. Time.time — ゲーム開始からの経過時間

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 が呼ばれてからの経過秒数が得られます。


3. 一定間隔でオンオフを繰り返す

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; に置き換えると、オブジェクトの表示・非表示を一定間隔で切り替える点滅エフェクトになります。


4. ゲーム時間と現実時間

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# 標準ライブラリの DateTimeDateTimeOffset を使います。詳しくは 補足: 現実時間の取得(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;
}

まとめ


理解度チェック

以下の問いに答えられるか確認しましょう。

  1. Time.timeTime.deltaTime の違いを説明してください。
  2. Time.timeScale = 0 にしたとき、Time.deltaTime ベースのタイマーはどうなりますか?
  3. 次のコードは何秒ごとに状態を切り替えますか?

    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;
            // 状態を切り替える処理
        }
    }
    
解答を見る
  1. Time.time はゲーム開始時を 0 とした累計経過時間。Time.deltaTime前のフレームから今のフレームまでの短い経過時間。
  2. Time.deltaTime0 になるため、_timer の積算が止まりタイマーが自動的にポーズされる。
  3. _interval = 1.5f なので、1.5秒ごとに切り替わる。

次のステップ

チュートリアル: 信号機 では、Update と Time を組み合わせたステートマシンパターンを総合演習として実装します。