スポンサーリンク
エラー・トラブルシューティング

UnityでTime.timeScaleが効かない原因と対処法|ポーズが動かない時の完全ガイド

エラー・トラブルシューティング

はじめに

Time.timeScaleを0にしたのに、なぜか処理が止まらなかったり、逆に全部止まってしまって何も動かなくなったり…。そんな経験、ありませんか?🙂

たとえばこんな状態です:

  • ポーズ中なのにUIアニメーションまで止まる
  • コルーチンが途中で止まって再開しない
  • シーンを切り替えたのにゲームが動かない

これ、実は「バグ」ではなくUnityの時間の仕組みを正しく理解していないことで起きる現象がほとんどなんです。

私も最初は「timeScaleを0にすれば全部止まるでしょ」と思っていて、UIまで止まって「あれ?」となったことがあります。そこから調べていくと、原因はかなりパターン化されていることに気づきました。

Time.timeScaleまわりのトラブルは、やみくもに直そうとするとハマりがちですが、原因ごとに切り分けていけば意外とあっさり解決できます。

ここでは、

  • なぜtimeScaleが効かないように見えるのか
  • どこを見れば原因を特定できるのか
  • 同じ問題を繰り返さない設計のコツ

このあたりを順番に整理していきます。




まず最初に確認すべき5つのポイント

いきなり原因を1つずつ探すよりも、まずは「よくあるパターン」を順番にチェックしたほうが圧倒的に早いです。 ここで挙げる5つは、実際にトラブルの原因になりやすい順に並べています。

まずは次のポイントを確認してみてください:

  • WaitForSecondsを使っていないか
  • Time.deltaTimeに依存していないか
  • GameObjectがinactiveになっていないか
  • Time.timeScaleを戻し忘れていないか
  • Invokeを使っていないか

この中で1つでも当てはまる場合、それが原因である可能性がかなり高いです。

ここで大事なのは、「止まっていることが正しいのかどうか」を先に判断することです。

処理の種類ポーズ中の挙動
ゲーム進行(移動・物理)止まるのが正常
UI・演出動くのが自然

たとえば、プレイヤーの移動が止まらないなら「問題」ですが、UIのアニメーションが止まっているならそれも「問題」です。

つまり、「全部止める」か「一部は動かす」かを設計で決めていない状態が、一番ハマりやすいポイントなんです。

このあと、それぞれの原因を「症状 → 原因 → 解決方法」の順で具体的に見ていきます。




Time.timeScaleが効かない原因まとめ

WaitForSecondsでコルーチンが止まる

ポーズ中に「一定時間後に処理が再開されるはずなのに、ずっと止まったまま」というケースはとても多いです。

症状

  • コルーチンが途中で止まる
  • ポーズ解除後も処理が進まない

原因

WaitForSecondsTime.timeScaleの影響を受けるため、timeScaleが0だと「時間が進まない=永遠に待機」になります。

解決方法

リアル時間ベースの待機に変更します。

yield return new WaitForSecondsRealtime(1f);

これで、ポーズ中でも1秒後に処理が再開されます。

注意点

ゲーム内の時間ではなく現実時間で進むため、スローモーション中でも処理速度は変わりません。

再発防止のコツ

  • ゲーム進行に関わる処理 → WaitForSeconds
  • UIや演出 → WaitForSecondsRealtime

deltaTime依存で処理が止まる

UIアニメーションやオブジェクトの移動が、ポーズ中に完全停止してしまう場合はここが原因です。

症状

  • ポーズ中にUIが動かない
  • アニメーションが完全に停止する

原因

Time.timeScale = 0のとき、Time.deltaTimeは0になります。 そのため、deltaTimeを使った計算はすべて停止します。

解決方法

ポーズ中も動かしたい処理には、次を使います。

Time.unscaledDeltaTime

判断基準

用途使う時間
ゲーム進行(移動・物理)deltaTime
UI・演出unscaledDeltaTime

時間処理の理解が曖昧な場合は、こちらの記事も参考になります。


GameObjectが非アクティブ

「そもそもコルーチンが動かない」という場合、時間とは別の原因の可能性があります。

症状

  • StartCoroutineが動かない
  • 途中で処理が消える

原因

コルーチンはアクティブなGameObject上でしか動作しません。 途中でSetActive(false)されると、その時点で停止します。

解決方法

  • 常に有効なオブジェクト(マネージャーなど)で実行する
  • 非アクティブにするタイミングを見直す

注意点

UIの表示切り替えでオブジェクトを丸ごと非アクティブにすると、裏で動いている処理も止まるので注意が必要です。


timeScaleのリセット漏れ

シーンを切り替えた後にゲームが動かない場合、ここを疑ってください。

症状

  • 新しいシーンでも停止状態
  • 何も操作できない

原因

Time.timeScaleはシーンをまたいでも保持されます。 そのため、0のままだと次のシーンも止まります。

解決方法

void Start()
{
    Time.timeScale = 1f;
}

シーン開始時に必ず初期化しておくと安心です。

ポーズ実装全体を見直したい場合はこちらも参考になります。


Invokeの仕様を誤解している

手軽に遅延処理を書けるInvokeですが、時間制御との相性はあまり良くありません。

症状

  • Invokeが実行されない
  • ポーズ中に止まる

原因

InvokeはtimeScaleの影響を受けるため、ポーズ中は実行されません。

解決方法

コルーチンに置き換えます。

IEnumerator Delay()
{
    yield return new WaitForSecondsRealtime(1f);
    // 処理
}

再発防止のコツ

  • 時間制御が絡む処理はCoroutineで統一する
  • Invokeは簡単な用途だけに使う



すぐ確認できる診断チェックリスト

ここまでの内容を踏まえて、「どこから確認すればいいか分からない…」という状態を防ぐために、短時間で原因を絞り込めるチェックリストを用意しました。

上から順番に確認していくと、無駄に悩まずに原因にたどり着けます。

  • □ コルーチン内で WaitForSeconds を使っていないか
  • Time.deltaTime を使った処理が止まっていないか
  • □ 対象のGameObjectが SetActive(false) になっていないか
  • Time.timeScale が0のままになっていないか
  • □ 遅延処理にInvokeを使っていないか

特に最初の2つ(WaitForSecondsとdeltaTime)は原因になりやすいので、ここを見直すだけで解決するケースも多いです。

もしチェックしても分からない場合は、「その処理はポーズ中に動くべきか?」を一度考えてみてください。

処理内容ポーズ中の正しい挙動
キャラクター移動止まる
物理演算止まる
UIアニメーション動く
演出(フェードなど)動く

この「正常な挙動の基準」を持っておくと、バグなのか仕様なのかを迷わなくなります。

なんとなく直そうとすると遠回りになりがちですが、チェックリストで順番に確認すれば、かなりの確率で短時間で解決できます。




よくある誤解と正しい理解

timeScaleを0にするとすべて止まる

「timeScaleを0にすれば全部止まる」と思いがちですが、実際にはそうなりません。

止まるのはtimeScaleに依存している処理だけです。

  • 止まる → 物理・移動・deltaTime依存の処理
  • 止まらない → UI・Realtime系・一部のAnimator設定

この違いを知らないまま実装すると、「止まるはずのものが動く」「動くはずのものが止まる」という混乱が起きやすくなります。

特にUIは「ゲームが止まっていても動いてほしい」ことが多いので、最初から分けて設計するのがポイントです。


WaitForSecondsはただの時間待ち

WaitForSecondsは「指定秒数待つ便利な処理」と思われがちですが、実際にはゲーム内時間に依存しています。

つまり:

  • timeScale = 1 → 普通に動く
  • timeScale = 0 → 永久に待機

この仕様を知らないと、「なぜか処理が再開しない」という現象にハマります。

ポーズ中でも動かしたい処理は、必ずRealtime系に切り替える必要があります。


deltaTimeは常に時間の経過を表す

deltaTimeは「フレームごとの時間差」としてよく使われますが、正確にはtimeScaleの影響を受けた時間です。

そのため:

  • timeScale = 1 → 通常の時間
  • timeScale = 0 → 0になる

UIや演出にdeltaTimeを使うと、ポーズ中に完全停止してしまう原因になります。

用途に応じて、

  • ゲーム進行 → deltaTime
  • UI・演出 → unscaledDeltaTime

この使い分けがとても重要です。


コルーチンはどこでも動く

コルーチンは便利ですが、どこでも自由に動くわけではありません。

実行にはMonoBehaviourがアタッチされたアクティブなオブジェクトが必要です。

そのため、

  • オブジェクトがinactive → コルーチンは停止
  • 途中でinactive → その時点で終了

UIの表示切り替えなどでオブジェクトごと無効化してしまうと、裏の処理も止まるので注意が必要です。


Invokeはコルーチンの代わりになる

Invokeは手軽に遅延処理が書けますが、時間制御という観点では制限があります。

特に注意したいのが、timeScaleの影響を受けるという点です。

つまり、ポーズ中はInvokeも止まります。

時間制御が関わる処理では、

  • Invoke → シンプルな用途向け
  • Coroutine → 制御が必要な処理向け

このように使い分けるとトラブルを減らせます。




再発しないための設計ルール

その場しのぎで直すこともできますが、時間制御は一度ハマると何度も同じ問題に出会いがちです。 ここでは、あとから困らないための設計の考え方をまとめておきます。

止める処理と止めない処理を分ける

まず一番大切なのはここです。

「ゲーム全体を止める」のではなく、

  • 止めたいもの(ゲーム進行)
  • 止めたくないもの(UI・演出)

これを明確に分けて考えることが重要です。

たとえばポーズ画面では、

  • プレイヤーの移動 → 止める
  • 背景のフェード → 動かす
  • メニューUI → 動かす

このように役割を分けて設計しておくと、timeScaleに振り回されなくなります。


UIはunscaled時間で動かす

UIに関しては、最初から「ポーズ中でも動く前提」で作るほうが安定します。

具体的には、

  • アニメーション → unscaledDeltaTime
  • 待機処理 → WaitForSecondsRealtime

このようにしておくと、後からポーズ機能を追加しても壊れにくくなります。

逆にdeltaTimeのまま作ってしまうと、「全部止まるUI」になってしまい、あとで修正が大変になります。


時間制御は1箇所にまとめる

複数のスクリプトでバラバラにtimeScaleを変更すると、かなり高い確率でバグになります。

よくある失敗パターンはこんな感じです:

  • ポーズ処理でtimeScale = 0
  • 別のスクリプトでtimeScaleを変更
  • どこで戻すのか分からなくなる

これを防ぐために、

  • 時間制御専用のマネージャーを作る
  • timeScaleはそこだけで変更する

こうしておくと、「どこで時間が変わっているか」が一目で分かります。


経験から分かるハマりやすいポイント

実際に開発していると、こんな流れでハマることが多いです。

  • とりあえずtimeScale = 0でポーズ実装
  • UIも止まって「あれ?」となる
  • 一部だけ動かそうとして処理がぐちゃぐちゃになる

最初は簡単に見えるのですが、後から修正すると意外と手間が増えます。

だからこそ、

  • 「時間の種類(scaled / unscaled)」を意識する
  • 最初から役割ごとに分けて設計する

この2つを押さえておくと、かなり安定した実装になります。


時間制御の理解をもう少し体系的に整理したい場合は、基礎から学び直すのもおすすめです。

Unity 3Dゲーム開発ではじめるC#プログラミング
✅ Amazonでチェックする✅ 楽天でチェックする




まとめ

Time.timeScaleが効かないと感じるとき、多くの場合は「Unityの時間の仕組み」と「使っているAPIの性質」がズレているだけです。

もう一度、優先順位を整理しておきます。

  1. WaitForSecondsを使っていないか
  2. deltaTimeに依存していないか
  3. GameObjectがinactiveになっていないか
  4. timeScaleを戻し忘れていないか
  5. Invokeを使っていないか

この順番で確認すれば、ほとんどのケースは短時間で原因にたどり着きます。


今回のポイントを一言でまとめると、

「時間には2種類ある(scaled / unscaled)」

これを理解しているかどうかで、実装の安定性がかなり変わります。

  • ゲーム進行 → scaled時間(timeScaleの影響を受ける)
  • UI・演出 → unscaled時間(影響を受けない)

この線引きができていれば、「止まるべきものが止まらない」「動くべきものが止まる」といったトラブルはほぼ防げます。


開発していると、「とりあえず動けばOK」で進めたくなる場面も多いですよね。 でも時間制御だけは、後から直すほど複雑になります。

最初の段階で、

  • どの処理を止めるか
  • どの処理を止めないか

ここを決めておくだけで、かなりスムーズに開発が進むようになります。

少しでも「なんで動かないんだろう…」と感じたら、今回のチェックポイントを思い出してみてください🙂


よくある質問(FAQ)

Q
timeScaleを0にしても動く処理はありますか?
A

あります。主にtimeScaleの影響を受けない処理です。

  • Time.unscaledDeltaTimeを使った処理
  • WaitForSecondsRealtimeを使ったコルーチン
  • UIの一部アニメーション(設定による)

「全部止まる」と思い込まず、どの時間を使っているかで判断するのがコツです。

Q
ポーズ中でもコルーチンを動かすにはどうすればいいですか?
A

Realtime系の処理に置き換えることで対応できます。

  • WaitForSeconds → WaitForSecondsRealtime
  • deltaTime → unscaledDeltaTime

これだけで、ポーズ中でも処理を継続できるようになります。

ただし、ゲーム進行に関わる処理まで動かしてしまうとバグの原因になるので、「どこまで動かすか」は意識して設計する必要があります。

Q
FixedUpdateはポーズ中どうなりますか?
A

FixedUpdateはtimeScaleの影響を強く受けるため、timeScaleを0にすると基本的に呼ばれなくなります。

つまり、

  • 物理演算 → 完全停止
  • Rigidbodyの挙動 → 更新されない

そのため、ポーズ中に物理を動かしたい場合は、別の仕組みで制御する必要があります。

通常は「ポーズ中は物理を止める」設計にするほうが自然です。

※当サイトはアフィリエイト広告を利用しています。リンクを経由して商品を購入された場合、当サイトに報酬が発生することがあります。

※本記事に記載しているAmazon商品情報(価格、在庫状況、割引、配送条件など)は、執筆時点のAmazon.co.jp上の情報に基づいています。
最新の価格・在庫・配送条件などの詳細は、Amazonの商品ページをご確認ください。

スポンサーリンク