スケールされない時間
CoddyのUnityジャーニー「本格的なゲームを作る」セクションの一部。レッスン 35/56。
ゲームが一時停止またはスローダウンしていても、一時停止メニューのアニメーション、プレイ再開までのカウントダウン、自動的に解除される必要があるフリーズなど、一部の処理には実時間の時計が必要です。Time.unscaledDeltaTimeはTime.timeScaleの値にかかわらず前のフレームからの実時間で、Time.unscaledTimeはゲーム開始からの実時間です。この一時停止メニューは実時間を使ってローディングホイールを回すため、ゲームが一時停止中もホイールが回転します。
void Update()
{
wheel.Rotate(0f, 0f, -180f * Time.unscaledDeltaTime); // 一時停止中かどうかにかかわらず、1秒間に半回転
}コルーチンにも同じ組み合わせがあります。WaitForSecondsはゲーム内時間を数えるため、Time.timeScale = 0では終了しません。一方、WaitForSecondsRealtimeは実際の秒数を数えます。メニューを開いたときに開始すると、このコルーチンはメニューのタイトルを0.5秒ごとに点滅させます。
IEnumerator Blink()
{
while (true)
{
title.SetActive(!title.activeSelf);
yield return new WaitForSecondsRealtime(0.5f);
}
}ゲームが停止したら止まるべきゲームプレイにはスケールされた値を使い、一時停止中やスローダウン中にも動作させる必要があるもの、つまりメニューやそのアニメーション、一時停止を解除するタイマーにはスケールされていない値を使います。Invokeには実時間版がなく、常にゲーム内時間を数えます。
チャレンジ
中級ヒットストップを使うと、強い打撃がより重く感じられます。衝撃の瞬間にゲーム全体が少しの間停止します。矢印キーでドロッパーを動かし、Spaceキーでドロッパーから金床を落とします(Dropper.csは準備済み)。各金床が持つAnvil.csを作成しましょう。
- 金床が何かに当たったら、ゲームを停止します。
Time.timeScaleを0にします。 freezeTime秒(実時間)が経過したら(Inspectorで0.3に設定)、1に戻します。
Playを押して金床をいくつか落とし、それからCheckを押してください。
自分で試してみよう
using System.Collections;
using UnityEngine;
public class Anvil : MonoBehaviour
{
public float freezeTime = 0.3f;
// 金床が何かに当たったら、ゲームを実時間でfreezeTime秒間停止する
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。