Menu
CoddyTech

スケールされない時間

CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 36/60。

ゲームが一時停止中またはスローモーション中でも、一時停止メニューのアニメーション、ゲーム再開前のカウントダウン、自動で解除される必要があるフリーズなどには、実時間の時計が必要です。Time.unscaledDeltaTimeは前のフレームからの実時間で、Time.timeScaleの値にかかわらず一定です。また、Time.unscaledTimeはゲーム開始からの実時間です。この一時停止メニューでは実時間を使ってローディングホイールを回すため、ゲームが一時停止中でもホイールは回転します。

void Update()
{
    wheel.Rotate(0f, 0f, -180f * Time.unscaledDeltaTime);   // 一時停止中かどうかに関係なく、毎秒半回転
}

コルーチンにも同じ2種類があります。WaitForSecondsはゲーム内時間を数えるため、Time.timeScale = 0では終了しません。一方、WaitForSecondsRealtimeは実時間の秒数を数えます。メニューを開いたときに開始すると、このコルーチンはメニューのタイトルを0.5秒ごとに点滅させます。

IEnumerator Blink()
{
    while (true)
    {
        title.SetActive(!title.activeSelf);
        yield return new WaitForSecondsRealtime(0.5f);
    }
}

ゲームが停止したときに停止すべきゲームプレイにはスケールされた値を使い、一時停止中やスローモーション中にも動作させる必要があるもの、つまりメニューやそのアニメーション、一時停止を終了させるタイマーにはスケールされていない値を使いましょう。Invokeには実時間版がなく、常にゲーム内時間を数えます。

challenge icon

チャレンジ

中級

金床にヒットストップを付けましょう。着地したとき、ゲーム全体が一瞬停止します。

  1. Anvil.csでIEnumerator HitStop()を記述します。まずTime.timeScale = 0f;、次にyield return new WaitForSecondsRealtime(freezeTime);を記述し、その後1fに戻します。
  2. StartCoroutine(HitStop());を呼び出すvoid OnCollisionEnter(Collision collision)を記述します。

「プレイ」を押し、Spaceキーで金床を落とします。着地するたびにゲームが0.3秒間停止します。その後、「確認」を押します。

自分で試してみよう

using System.Collections;
using UnityEngine;

public class Anvil : MonoBehaviour
{
    public float freezeTime = 0.3f;

    // 金床が何かに当たったとき、ゲームを実時間でfreezeTime秒間停止する
}

本格的なゲームを作るのすべてのレッスン

自分で練習してみよう: Unityプレイグラウンド