Developer

【初心者Unity】Time.timeScaleの基本的な使い方
2021.10.31
Lv1

【初心者Unity】Time.timeScaleの基本的な使い方

1.はじめに

本記事では、時間の速さを管理するための機能であるTime.timeScaleについて解説します。
Time.timeScaleを使用することで、以下のことが実現できます。

  • スローモーション
  • クイックモーション
  • ポーズ(一時停止) etc…

これらの機能を実装したいという方は是非ご一読ください!

2.Time.timeScaleとは

Time.timeScaleの話をする前に、前提となる2つの時間の話をしましょう。

Unityが扱う時間には「現実世界の時間」と「Unity内の時間」の2種類があります(正式名称ではありませんが…)。
例えば、ゲーム内の演出でキャラクターがスローモーションで動くようなものがあるとします。
この時、「Unity内の時間」は「現実世界の時間」よりもゆっくり流れている、ということになります。
あるいは、ゲームをポーズしている時、「Unity内の時間」は止まっていますが、「現実世界の時間」は当然動いています。

…と漠然とした話をしてもイメージが付き辛いでしょうか。
具体的には、アニメーションの再生速度や物理演算などは、「Unity内の時間」の速さに従うことになります。
一方で、ゲームのプレイ時間などは「現実世界の時間」に合わせて計算する必要があります。
※厳密には、アニメーションの再生速度はTime.timeScaleに従わないように設定できます。後述します。

それを踏まえて…
Time.timeScaleは「Unity内の時間」の経過する速さを表す変数です。
初期値は1で、これは「現実世界の時間」の速さと等しいことを意味しています。
例えばこの値を0.5にすると、「現実世界の時間」の半分の速さでゆっくりと時間が流れ、
値を2にすると、「現実世界の時間」の倍の速さですばやく時間が流れる、といった具合になります。
つまり、「現実世界の時間」の速さとの比を設定値として持つわけです。

設定値はEdit > Project Settings > Timeで確認できます。

3.Time.timeScaleの使い方

では実際に、Time.timeScaleの動作を見てみましょう。
以下のようなカウントアップタイマーを用意してみました。
(実装方法については【初心者Unity】Time.deltaTimeの基本的な使い方をご覧ください。)

このタイマーはTime.deltaTimeで実装されています。
Time.deltaTimeやTime.timeはTime.timeScaleの影響を受けるパラメータの代表格です。
ゲームの再生中にTime Scaleの値を変化させてみます。

Time Scaleの値によってタイマーの進む速度が変わりましたね。
特に値が0の時には、タイマーが完全に止まってしまいました。
この性質はポーズ機能の実装で良く使われています。

次に物理演算への影響についても見てみましょう。
似たような構成で、SquareをRigidbody2Dのvelocityで動かしています。

Time Scaleの値が0になったタイミングで止まりました。

この他にも、以下の処理はTime.timeScaleによって制御が可能です。

  • Time.time
  • FixedUpdate
  • 物理演算

4.Time.timeScaleの影響を受けたくない場合

次にTime.timeScaleの影響を受けない設定について見ていきましょう。
具体的なイメージとしては、ポーズ画面でキャラクターが動いていたり、ゲームのプレイ時間を計測したり、といった場面が想定されるでしょうか。

フレームの経過時間を使いたい
フレームの経過時間を使用する場合、基本的にはTime.deltaTimeを使うことになります。
ですが、Time.deltaTimeはTime.timeScaleの影響を受けてしまいます。
(フレームの経過時間を使う理由は【初心者Unity】Time.deltaTimeの基本的な使い方をご覧ください。)

Time.deltaTimeを使いたいけれども、Time.timeScaleの影響は受けたくない。

そのような場合は、Time.unscaledDeltaTimeを使うと良いでしょう。
先ほどのカウントアップタイマーを例に比較してみます。

Time.unscaledDeltaTimeはTime.deltaTime同様、前回のフレームからの経過時間(秒)を表していますが、
Time.deltaTimeとは異なりTime.timeScaleの影響を受けません。
そのため、Time.unscaledDeltaTimeを使ったタイマーはTime.timeScaleの値によらず一定の速さで進み続けています。

アニメーションを再生したい
アニメーションに関しても、Time.timeScaleの影響を受けない設定にすることができます。
デフォルトの設定では、アニメーションの再生速度はTime.timeScaleの影響を受けますが、
AnimatorコンポーネントのUpdate ModeをUnscaled Timeに設定することでTime.timeScaleの影響を受けなくなります。

この他にも、以下の処理はTime.timeScaleの影響を受けません。

  • Time.unscaledTime
  • Update
  • Transformの操作

5.(おまけ)Time.timeScaleの仕組み

少し込み入った話ですが、Time.timeScaleはTime.deltaTime等の値を算出する際に乗算されています。

Time.deltaTime = 前回のフレームからの経過時間 * Time.timeScale

そのため、Update関数はTime.timeScaleの影響を受けなくても、Time.deltaTimeは影響を受けてしまうんですね。
また、Rigidbody等の物理演算は内部でTime.deltaTime等を使用しているため、こちらもTime.timeScaleの影響を受けてしまう訳です。

6.おわりに

Time.timeScaleの使い方について簡単に解説しました。
今回の記事で解説した内容は頻出ですので、是非ご自身で実装できるように練習してみて下さい。
また、関連記事として以下を紹介します。併せてご確認ください。

【初心者Unity】Time.deltaTimeの基本的な使い方
【初心者Unity】Time.timeの基本的な使い方
【初心者Unity】Time.deltaTimeとTime.timeの使い分け

 

連載目次リンク

「初心者のための」Unityゲーム制作 目次
 

Unity実践編 - 目次リンク

実践Unityゲームプログラミング 連載目次