top of page

UnityのTime.deltaTimeの使い方 徹底まとめ

  • 16 時間前
  • 読了時間: 8分

この記事はファイブボックス公式 note の記事を編集したものです。併せてリンクの記事もご参照ください。


移動・タイマー・カウントダウンでよく使う時間処理

Unityでゲームを作っていると、よく出てくるのが

Time.deltaTime

です。

最初は少し分かりにくいですが、キャラクターの移動、タイマー、カウントダウン、敵の出現間隔など、いろいろな場面で使います。

この記事では、Unity初心者の方向けに、Time.deltaTime の基本的な考え方と、よく使うコード例をまとめていきます。



Time.deltaTimeとは?

Time.deltaTime は、簡単に言うと、前のフレームから今のフレームまでにかかった時間

を表します。


1,移動を一定速度にする

Unity の Update() は、1秒間に何度も呼ばれます。ただし、呼ばれる回数はパソコンやスマホの性能、ゲームの重さ、同時に動いている他のシステム等によって変わります。

例えば、

  • 1秒間に60回 Update() が呼ばれるデバイスの場合

  • 1秒間に30回 Update() が呼ばれるデバイスの場合

では、同じコードを書いていても、処理される回数が変わってしまいます。

そのため、何も考えずに毎フレーム位置を動かすと、環境によって動く速さが変わってしまうことがあります。

ここで使うのが Time.deltaTime です。


Time.deltaTimeを使わない移動

まずは、Time.deltaTime を使わない移動を見てみます。

void Update()
{
    transform.position += Vector3.right * 0.1f;
}

このコードでは、Update() が呼ばれるたびに、オブジェクトが右方向に 0.1 ずつ移動します。

一見問題なさそうですが、実はこの書き方だと、Update() が多く呼ばれる環境ほど速く動いてしまいます。

例えば、

1秒間のUpdate回数ごとの移動量をまとめた表

このように、FPSが高いほど移動量が増えてしまいます。


FPS は Frames Per Second の略です。意味は、1秒間に何枚のフレーム、つまり画面を表示・更新できるか です。


TimeDeltaTime の移動量まとめ

Time.deltaTimeを使った移動

次に、Time.deltaTime を使った移動です。

public float speed = 5f;

void Update()
{
    transform.position += Vector3.right * speed * Time.deltaTime;
}

このように書くと、speed は1秒間にどれくらい進むか という意味になります。

例えば speed = 5f なら、1秒間に 5 進むという考え方です。

Time.deltaTime をかけることで、1フレームごとの移動量ではなく、1秒あたりの移動量として扱えるようになります。

そのため、FPSが違っても、だいたい同じ速さで動かすことができます。


よく使う移動コード

実際のゲームでは、キー入力に合わせてキャラクターを動かすことが多いです。

例えば、左右移動なら次のように書けます。

public float speed = 5f;

void Update()
{
    float x = Input.GetAxisRaw("Horizontal");

    Vector3 direction = new Vector3(x, 0, 0);

    transform.position += direction * speed * Time.deltaTime;
}

左右だけでなく、上下にも動かしたい場合は次のようになります。

public float speed = 5f;

void Update()
{
    float x = Input.GetAxisRaw("Horizontal");
    float y = Input.GetAxisRaw("Vertical");

    Vector3 direction = new Vector3(x, y, 0).normalized;

    transform.position += direction * speed * Time.deltaTime;
}

ここで .normalized を使っているのは、斜め移動が速くなりすぎないようにするためです。

左右だけ、上下だけの移動では問題ありませんが、右上や左下などの斜め方向に移動すると、縦と横の移動が同時に行われます。そのままだと斜め移動だけ少し速くなってしまうため、.normalized で方向の長さをそろえています。


GetAxisRaw

float x = Input.GetAxisRaw("Horizontal");
float y = Input.GetAxisRaw("Vertical");

この部分では、キーボードの入力を取得しています。

Horizontal は横方向の入力、Vertical は縦方向の入力を表します。


■ Horizontal

Horizontal は、横方向の入力です。

  • 右キー、または Dキーを押す → 1

  • 左キー、または Aキーを押す → -1

  • 何も押していない → 0

つまり、右に進みたいときは 1、左に進みたいときは -1、止まっているときは 0 になります。


■ Vertical

Vertical は、縦方向の入力です。

  • 上キー、または Wキーを押す → 1

  • 下キー、または Sキーを押す → -1

  • 何も押していない → 0


つまり、上に進みたいときは 1、下に進みたいときは -1

、止まっているときは 0 になります。


GetAxis の Horizontal とVertical

2,タイマーとして使う

Time.deltaTime は、移動だけでなくタイマーにもよく使います。

例えば、3秒たったら処理を実行したい場合は、次のように書けます。

float timer = 0f;

void Update()
{
    timer += Time.deltaTime;

    if (timer >= 3f)
    {
        Debug.Log("3秒経過しました");
        timer = 0f;
    }
}

このコードでは、timer に毎フレーム Time.deltaTime を足しています。

つまり、

timer += Time.deltaTime;

によって、経過時間を少しずつ積み上げています。timer が3以上になったら、3秒たったと判断しています。

この考え方は、ゲーム制作でとてもよく使います。

例えば、

  • 3秒ごとに敵を出す

  • 5秒たったらアイテムを消す

  • 一定時間ごとにスコアを増やす

  • 制限時間を管理する


といった処理に使えます。イベントが終わったら timer を 0 に戻すのを忘れずに!

イメージ的には「ししおどし」にとてもよく似ています。timer += Time.deltaTimeは、ししおどしに少しずつ水がたまっていくイメージです。毎フレームごとに少しずつ時間が加算され、一定量までたまると、ししおどしが「カコン」と傾くようにイベントが発動します。そして、

timer = 0f;

によって中身を空にし、また次の時間をため始めます。


TimeDeltaTimeは鹿威しのようなものを説明した画像

3,カウントダウンタイマーとして使う

次は、制限時間のようなカウントダウンです。

public float timeLimit = 60f;

void Update()
{
    timeLimit -= Time.deltaTime;

    if (timeLimit <= 0f)
    {
        timeLimit = 0f;
        Debug.Log("時間切れ");
    }
}

このコードでは、timeLimit から毎フレーム Time.deltaTime を引いています。

timeLimit -= Time.deltaTime;

これによって、時間が少しずつ減っていきます。

timeLimit が0以下になったら、時間切れの処理を行います。


UIに残り時間を表示する

ゲームでは、残り時間を画面に表示したいことが多いです。

例えば、Textを使って表示する場合は、次のように書けます。

public float timeLimit = 60f;
public Text timerText;

void Update()
{
    timeLimit -= Time.deltaTime;

    if (timeLimit <= 0f)
    {
        timeLimit = 0f;
    }

    timerText.text = Mathf.CeilToInt(timeLimit).ToString();
}

Mathf.CeilToInt() は、小数を切り上げて整数に変換する命令です。

例えば、残り時間が 59.2 秒のとき、画面には 60 と表示されます。残り時間の表示では、小数のまま表示するよりも、整数にした方が見やすくなります。

【画像:残り時間UIの表示例】ここに、画面上に「60」「59」「58」と表示される画像を入れる。


一定時間ごとに敵を出す

Time.deltaTime を使うと、一定時間ごとに敵やアイテムを出す処理も作れます。

public GameObject enemyPrefab;
public float spawnInterval = 2f;

float timer = 0f;

void Update()
{
    timer += Time.deltaTime;

    if (timer >= spawnInterval)
    {
        Instantiate(enemyPrefab);
        timer = 0f;
    }
}

このコードでは、timer が spawnInterval 以上になったら敵を出しています。

spawnInterval が 2f なら、2秒ごとに敵が出ます。

この考え方を使うと、

  • 敵を一定間隔で出す

  • アイテムを一定間隔で出す

  • 障害物を一定間隔で出す

  • 時間経過で難易度を上げる


といった処理を作ることができます。

【動画:2秒ごとに敵が出る例】ここに、敵が一定間隔で出現する動画を入れる。


コルーチンとの違い

前回の記事では、コルーチンについてまとめました。

コルーチンでは、次のように書くことで、数秒待ってから処理を行うことができます。

yield return new WaitForSeconds(3f);

一方、Time.deltaTime を使う場合は、毎フレーム時間を数えながら処理します。

timer += Time.deltaTime;

どちらも時間に関係する処理ですが、得意な場面が少し違います。

方法向いている処理Time.deltaTime毎フレーム時間を見ながら処理したいコルーチン数秒待ってから次の処理をしたいInvoke簡単に遅延実行したい

例えば、制限時間のように、毎フレーム残り時間を表示したい場合は Time.deltaTime が向いています。

逆に、3秒待ってからシーンを切り替えるだけなら、コルーチンの方が分かりやすい場合もあります。


Invokeとの違い

Unityには、Invoke() という命令もあります。

Invoke("GameOver", 3f);

これは、3秒後に GameOver という関数を呼び出す書き方です。

簡単な遅延処理には便利ですが、関数名を文字列で書くため、関数名を変更したときにミスが起きやすいという注意点もあります。

そのため、初心者のうちは、

  • 毎フレーム時間を管理したいなら Time.deltaTime

  • 順番に待ちながら処理したいならコルーチン

  • 簡単に数秒後に呼びたいだけなら Invoke


というイメージで覚えておくとよいと思います。


Time.timeScaleとの関係

少し発展的な内容ですが、Time.deltaTime は Time.timeScale の影響を受けます。

Time.timeScale は、ゲーム内の時間の流れを変えるための値です。

例えば、

Time.timeScale = 0f;

とすると、ゲーム内の時間が止まります。

この状態では、Time.deltaTime もほぼ進まなくなります。

つまり、

  • キャラクターの移動が止まる

  • 敵の移動が止まる

  • カウントダウンタイマーが止まる


ということが起こります。

ポーズ画面を作るときには、この仕組みを使うことがあります。例えば以下のコードは、一時停止と再開を兼ね備えたボタン(トグルスイッチ)にセットする関数です。

isPaused は、現在ゲームが一時停止中かどうかを覚えておくための変数です。

bool isPaused = false;

最初はゲームが動いている状態なので、false にしておきます。

ボタンが押されたときに TogglePause() が呼ばれます。

public void TogglePause()
{
    if (isPaused == false)
    {
        Time.timeScale = 0f;
        isPaused = true;
    }
    else
    {
        Time.timeScale = 1f;
        isPaused = false;
    }
}

isPaused が false のときは、まだポーズしていない状態です。そのため、Time.timeScale = 0f; にしてゲーム内の時間を止めます。

そのあと、isPaused = true; にして、現在ポーズ中であることを記録します。

逆に、isPaused が true のときは、すでにポーズ中です。そのため、Time.timeScale = 1f; に戻してゲームを再開します。

そのあと、isPaused = false; にして、ポーズが解除されたことを記録します。


Time.unscaledDeltaTimeとは?

Time.timeScale の影響を受けずに、実際の時間を使いたい場合は、

Time.unscaledDeltaTime

を使います。

例えば、ゲームをポーズしていても、ポーズメニューのアニメーションだけは動かしたい場合などに使います。

初心者のうちは、まずは Time.deltaTime をしっかり理解できれば大丈夫です。Time.unscaledDeltaTime は、ポーズ中でも動かしたいものが出てきたときに覚えるとよいです。


まとめ

Time.deltaTime は、Unityで時間を扱うときによく使う大切な仕組みです。

特に、

  • キャラクターを一定の速さで動かす

  • 経過時間を数える

  • カウントダウンを作る

  • 一定時間ごとに敵を出す

  • ポーズ中の時間制御を考える


といった場面で使います。

最初は少し分かりにくいですが、

Time.deltaTimeは、前のフレームから今のフレームまでにかかった時間

と考えると理解しやすくなります。

そして、移動処理では、

speed * Time.deltaTime

と書くことで、FPSに左右されにくい動きを作ることができます。

前回まとめたコルーチンとあわせて覚えると、Unityでの時間処理のバリエーションが充実してくると思います。

コメント


bottom of page