【初心者Unity】Time.timeScaleの基本的な使い方
▶
【Unity】3Dアクションゲームを作ろう!#7 ステージの作成(Skybox・落下判定)
▶
【Unity】3Dアクションゲームを作ろう!#8 ステージの作成(スイッチ・扉)
▶
【Unity】3Dアクションゲームを作ろう!#9 プレイヤーのHP管理
▶
【初心者Unity】JsonUtilityクラスでJSONを扱う方法
▶
【初心者Unity】スクリプトからコンポーネントを追加する方法
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等の値を算出する際に乗算されています。
そのため、Update関数はTime.timeScaleの影響を受けなくても、Time.deltaTimeは影響を受けてしまうんですね。
また、Rigidbody等の物理演算は内部でTime.deltaTime等を使用しているため、こちらもTime.timeScaleの影響を受けてしまう訳です。
6.おわりに
Time.timeScaleの使い方について簡単に解説しました。
今回の記事で解説した内容は頻出ですので、是非ご自身で実装できるように練習してみて下さい。
また、関連記事として以下を紹介します。併せてご確認ください。
【初心者Unity】Time.deltaTimeの基本的な使い方
【初心者Unity】Time.timeの基本的な使い方
【初心者Unity】Time.deltaTimeとTime.timeの使い分け