Unityの一時停止で止まるもの、止まらないもの【Time.timeScale】


Unityの一時停止で止まるもの、止まらないもの【Time.timeScale】


Unityにおける一時停止といえば「Time.timeScale = 0 」ですが、いざ止めてみたらなんか動いてるやつがいるぞ…。
なんてことありませんか?そんなときはTimeScaleです。

ws000612

Time.timeScale は時間の経過をスケールするためのプロパティです。
時間に依存しない処理は「止まらない」場合があるため、そこらへんをしっかり把握する必要があります。

止まらない例①


いくつか例を見てみましょう。

例えば、以下の処理は「Time.timeScale = 0 」で止まりません。

	void Update() {
		Debug.Log("止まるのか?いや、止まらない!");
	}

一方、こちらの場合は止まります。

	void FixedUpdate() {
		Debug.Log("止まります!");
	}

つまり
・Update関数は、「Time.timeScale = 0 」にしても止まりません。
・FixedUpdate関数は、「Time.timeScale = 0 」で止まります。(関数が呼び出されない)

そもそもUpdateが止まっちゃったら、入力すら受け付けなくなっちゃうので、timeScaleを1に戻せないですよね。

止まらない例②


もう一つ例を見てみましょう。今度は両方ともUpdateでの処理です。

こちらの処理は止まります。

	void Update() {
		GetComponent<Rigidbody>().velocity = new Vector3(1.0f, 0, 0);
	}

※Update内でGetComponentをしていますが、本来はStartでやる方が良し。

一方、こちらの処理は止まりません。

	void Update() {
		transform.Translate(1.0f, 0, 0);
	}

Rigidbodyへの操作は、フレーム経過時間が加味されるため、Update内に記述しても止まります。
(※本来、物理演算はFixedUpdateに記述すべきですが、今回は突っ込まない方向で)
しかし、Transformへの操作は、上記の記述ではフレーム経過時間が加味されていないため、止まりません。

そもそもですが、Update内における描画に影響するような操作(座標の変更など)は、実行環境によるフレームレートの違いを補うために、フレーム経過時間を加味した記述にすべきです。

したがって、以下のように記述します。

	void Update() {
		transform.Translate(1.0f * Time.deltaTime, 0, 0);
	}

上記の様に記述しておけば、移動量に前フレームからの経過時間が乗算されるため、「Time.timeScale = 0」となった時には、ちゃんと止まるようになります。

まとめ


「Time.timeScale = 0 」による一時停止は
・Updateは止まる。
・FixedUpdateは止まらない。
・Update内でも、時間を加味していない処理は止まらない。
・物理演算はどこに記述しても強制的に止まる。

以上のことを踏まえたうえで、効率的に利用してきましょう。

最近よく読まれている記事

【新着】Unityで主観カメラへの切り替えと、プレイヤーの移動方法について
【注目】Unityでマウスホイールでカメラの向きにドリーイン・ドリーアウトさせる
【知らないと危ない】UnityのactiveSelfとactiveInHierarchyの違いについて
【鉄板】Unityでカメラの向きを基準に移動する方法と、追従して回転できるカメラの実装

Unityの記事一覧にもどる

  • このエントリーをはてなブックマークに追加

PAGE TOP