未缩放时间
本课属于 Coddy Unity 学习旅程的“打造真正的游戏”单元。第 36 课,共 60 课。
游戏暂停或变慢时,有些事情仍需要按真实时间运行:会动起来的暂停菜单、继续游戏前的倒计时,以及必须自动结束的冻结效果。无论 Time.timeScale 是多少,Time.unscaledDeltaTime 都表示自上一帧以来经过的真实时间,而 Time.unscaledTime 表示从游戏开始到现在经过的真实时间。这个暂停菜单使用真实时间转动加载图标,因此游戏暂停时图标仍会旋转:
void Update()
{
wheel.Rotate(0f, 0f, -180f * Time.unscaledDeltaTime); // 每秒转半圈,无论是否暂停。
}协程也有这两种时间。WaitForSeconds 按游戏时间计时,因此当 Time.timeScale = 0 时,它永远不会结束;WaitForSecondsRealtime 按真实秒数计时。这个协程会在菜单打开时启动,每半秒让菜单标题闪烁一次:
IEnumerator Blink()
{
while (true)
{
title.SetActive(!title.activeSelf);
yield return new WaitForSecondsRealtime(0.5f);
}
}游戏玩法使用缩放后的时间值,因为游戏停止时玩法也应该停止;对于暂停或变慢时仍必须运行的内容,则使用未缩放的时间值,例如菜单、菜单动画,以及用于结束暂停的计时器。Invoke 没有按真实时间计时的版本:它始终按游戏时间计时。
挑战
中等让铁砧产生打击停顿:落地时,整个游戏会暂停片刻。
- 在
Anvil.cs中,编写IEnumerator HitStop():执行Time.timeScale = 0f;,然后执行yield return new WaitForSecondsRealtime(freezeTime);,再将它恢复为1f。 - 编写
void OnCollisionEnter(Collision collision),在其中调用StartCoroutine(HitStop());。
按下“开始”,再按空格键放下铁砧:每次落地都会让游戏暂停 0.3 秒。然后点击“检查”。
亲手试试
using System.Collections;
using UnityEngine;
public class Anvil : MonoBehaviour
{
public float freezeTime = 0.3f;
// 当铁砧撞到物体时,让游戏暂停 freezeTime 秒(现实时间)。
}
打造真正的游戏中的所有课
自己练习: Unity 在线编辑器