【Unity】timeScaleとは?ゲーム内の時間を進める速さを決める変数

timeScaleとは? Unity

こんにちは、ともくんのゲーム作り部屋にようこそ!

このページでは、

「UnityのtimeScaleってどんな変数なの?」

「timeScaleはどうやって使うの?」

というお悩みの方に向けた内容となっています。

Unityでは、ゲーム内の時間が経過する速さを決める変数としてtimeScaleというものがあります。

このtimeScaleはfloat型の変数で、デフォルトが「1」の値となっていて、現実時間と進む速さが同じになっています。

このtimeScaleの値を変更すると、ゲーム内の時間の進む速さが変わるので、例えばスローモーションの動きや早送りの機能を作る際に使います。

そこで、このページでは、UnityのtimeScaleという変数について、どんな仕組みになっているのか、また使い方までをまとめていきます。

この記事を書いた人

ゲーム作りを学び始めた一児のパパです。
このブログは、子供から「ゲームを作ってみたい!」と言われ、非プログラマーでゲーム作りをしたことない僕が、ゲーム作りの本を読んで独学でゲーム開発を学んでいるブログです。
同じように初めてゲーム作りをしている方と一緒に学んでいけるようなブログに出来たらいいなと思っています。
また、「このコードはおかしい」とか「もっと良い書き方があるよ!」などあれば、どんどん指摘して頂けると助かります。

timeScaleとは?

まずは、timeScaleがどんな変数なのかを紹介していきます。

ゲーム内の時間を経過させる速さを決めている

timeScaleは、冒頭でも解説した通り、ゲーム内の時間の速さを決めている変数となっています。

このtimeScaleのデフォルト値は「1」となっていて、デフォルトの場合は現実時間とUnity内の時間の進む速さが同じ状態となっています。

例えば、ゲームを開始してから経過した時間を計測できるTime.timeの変数をゲーム内に表示させてみます。

timeScaleが「1」の場合でゲームを開始すると、以下のように現実世界と同じ時間速度で計測されているのが分かります。

次に、このtimeScaleを「2」に変更してゲームを開始すると、Unity内の時間の進む速さが2倍になり、現実世界で1秒経過すると、Unity内では2秒経過したことになります。

また、timeScaleを「0.5」に変更してみると、Unity内の時間の進む速さは1/2となり、現実世界で1秒経過しても、Unityでは0.5秒しか経過していないことになります。

このようにtimeScaleを変更することで、ゲーム内の時間を経過させる速さを変更することができます。

スローモーションなどを表現する際に使用する

timeScaleを途中で変更することで、ゲーム内でスローモーションを作成したり、反対に進むスピードを早めて早送りするという機能などを作成することができます。

先ほどはtime変数で現実世界との時間計測で比較しましたが、timeScaleを変更するとそれに応じてゲーム内の処理に対しての速度自体が変わることになります。

例えば、以下のようにオブジェクトがぐるぐると回る動きを作ってみました。

上記は、timeScaleが「1」の値の動きになっています。

このtimeScaleの値をスクリプトなどから途中で変更してあげることで、

上のようにスローモーションになる動き(timeScaleを「0.5」に変更)を作ったり、

早送りされるような動き(timeScaleを「2」に変更)を作ることができます。

ここでは、オブジェクトの動きの一つのみで紹介していますが、timeScaleを変更するとすべての処理における速度が変更されることになります。

フレームの経過時間が変わるため注意

timeScaleを使う際の注意点として、フレームの経過時間も変わることになります。

例えば、フレームの経過時間を計測するのに、よく使われるのがdeltaTimeという変数です。

timeScaleを変更すると全体の進む時間が変更されるので、deltaTimeで5秒経過した際の処理を作っていたとしても、5秒の進む時間が現実世界と変わることになるため、想定していた動きにならない場合があります。

もし、timeScaleで時間の速さを変更しているけど、スクリプト内での処理では現実世界と同じ時間で行いたいという場合には、deltaTimeではなくunscaledDeltaTimeという変数を使いましょう。

このunscaledDeltaTimeは、timeScaleの値に影響されずに、現実世界と同じ時間で前のフレームとの経過時間を計測してくれる変数となっています。

また同様に、ゲーム開始からの経過時間を計測できるtime変数も、timeScaleの値に影響されないunscaledTimeという変数を使えば、現実世界と同じ時間で計測することができます。

timeScaleの使い方

ここからは、実際にtimeScaleの使い方を紹介していきます。

timeScaleをUnityエディターから直接変更する

timeScaleは、Unityのエディター上から直接変更することができます。

timeScaleを変更する際は、メニューの「Edit」から「Project Settings…」を選択します。

そして、開いた画面の左側から「Time」を選択してあげます。

すると、「Time Scale」という項目が表示されていて、デフォルトでは「1」が入っていますが、この値を変更することで、ゲーム内の時間の速さを変えることができます。

Time.timeScaleで値をスクリプトから変更する

ゲーム内の途中やゲームの設定画面などから、timeScaleの値を変更したい場合は、スクリプトから変更処理を行う必要があります。

timeScaleは、Timeクラスで定義されている変数なので、以下のようにスクリプト内で記述することができます。

Time.timeScale

例えば、スペースキーを押した場合に、timeScaleの値を「2」にしたい場合は、

using UnityEngine;

public class Test : MonoBehaviour
{
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {
            Time.timeScale = 2.0f;
        }
    }
}

上記のように記述してあげることで、スペースキーを押すと時間の経過する速度が2倍になります。

なお、timeScaleはfloat型の変数なので、後ろに「f」を付けておくのを忘れないようにしておきましょう。

スローモーションの処理を作る

ここでは、timeScaleの変数を使ってゲーム内でスローモーションになる動きを作ってみます。

まず、2つのボールとなるオブジェクトにRigidbodyを使って、画面内を移動させるような動きを付けておきます。

そして、この2つのボールが衝突した際、動きをスローモーションに変更し、2秒間経過したら元の時間の速さに戻すという処理を作っていきます。

空のオブジェクトを作成して、以下のスクリプトを紐づけておきます。

using UnityEngine;

public class MotionController : MonoBehaviour
{
    bool isSlowing = false; // スローモーションしているかどうかを判定する変数
    float delta;    // スローモーションの経過時間を計測する変数

    public void SlowMotion()
    {
        Time.timeScale = 0.2f;  // ゲーム内の時間をスローにする処理
        isSlowing = true;
    }

    void Update()
    {
        if (isSlowing)
        {
            delta += Time.unscaledDeltaTime;    // 経過時間を計測

            if (delta > 2.0f)
            {
                Time.timeScale = 1.0f;  // ゲーム内の時間を戻す処理
                isSlowing = false;
                delta = 0;
            }
        }
    }
}

8行目でスローモーションにする処理を行うSlowMotionメソッドを作成して、その中の10行目でtimeScaleの値を「0.2」に変更しておきます。

スローモーションになったかどうかは、5行目で宣言しているisSlowingというbool型の変数で判定させています。

そして、isSlowingがtrueになった際にUpdateメソッド内の16行目から26行目で、unscaledDeltaTimeを使って現実時間での2秒間の計測を行い、2秒を超えたらtimeScaleを元に戻すという処理を行っています。

あとは、どちらか片方のボールに以下のスクリプトをアタッチしておきます。

using UnityEngine;

public class BallController : MonoBehaviour
{
    public MotionController motion; // インスペクターウィンドウから代入

    void OnCollisionEnter2D(Collision2D collision)
    {
        if (collision.gameObject.name == "ball2")
        {
            motion.SlowMotion();    // スローモーションの処理を行う
        }
    }
}

7行目で衝突した際に呼び出せるOnCollisionEnter2Dメソッド内で、先ほど作成したSlowMotionのメソッドを呼び出すようにしています。

これでゲームを実行してみると、

ボールが衝突すると、スローモーションで動きがゆっくりになり、2秒経過すると元の速さに戻っているのが分かります。

まとめ

このページでは、UnityのtimeScaleという変数について、どんな変数なのか、また使い方までをまとめていきましたが、いかがでしたでしょうか?

timeScaleとは、ゲーム内の時間の速度を決めているfloat型の変数で、デフォルトでは「1」で現実世界と同じ時間計測を行うことができます。

このtimeScaleを変更することで、ゲーム内でスローモーションになる動きを作ったり、早送りする機能を作ることができます。

ただし、フレーム間の時間を計測するdeltaTimeの時間も変わってしまうため、timeScaleを変更しても現実世界と同じ時間で計測したい場合は、unscaledDeltaTimeを使う必要があります。

最後までお読みいただきまして、ありがとうございました!

コメント