Menu
CoddyTech

使用 timeScale 暂停

本课属于 Coddy Unity 学习旅程的“打造真正的游戏”单元。第 34 课,共 60 课。

Time.timeScale 表示游戏时间的运行速度:1 是正常速度,0 则会停止。设为 0 时,Time.deltaTime 的值为 0,因此所有写成 speed * Time.deltaTime 的移动都会停下来。此时不再调用 FixedUpdate(),所以刚体会悬在空中;WaitForSeconds 和 Invoke 也会等待,因为它们计算的是游戏时间。这个脚本通过按钮切换暂停状态,按钮的 On Click 列表会调用 TogglePause,并在暂停时显示面板:

public class PauseToggle : MonoBehaviour
{
    public GameObject pausePanel;
    bool paused;

    public void TogglePause()
    {
        paused = !paused;
        Time.timeScale = paused ? 0f : 1f;
        pausePanel.SetActive(paused);
    }
}

并不是所有东西都会停止。Update() 和 LateUpdate() 仍会在每帧调用,此时 Time.deltaTime 为 0;协程中的 yield return null 仍会在下一帧返回,UI 也仍能接收点击,因此按钮可以结束暂停。按键也仍会被读取:如果青蛙在 Update() 中按下空格键时跳跃,那么它会在暂停期间响应按键,并在暂停结束后的第一个物理步中跳起来。它的脚本会在时间停止时忽略按键:

void Update()
{
    if (Time.timeScale == 0f) return;   // 暂停时:忽略按键输入
    if (Input.GetKeyDown(KeyCode.Space))
    {
        rb.AddForce(Vector3.up * jump, ForceMode.Impulse);
    }
}

Time.timeScale 作用于整个游戏,而不是某个场景:如果在它为 0 时加载另一个场景,新场景也会以暂停状态开始。重启或退出关卡的菜单按钮应先将它设回 1。

challenge icon

挑战

中等

为网球场添加暂停菜单。场景已连接“暂停”和“继续”按钮。

  1. 在 PauseMenu.cs 中,Pause() 会设置 Time.timeScale = 0f;,并调用 panel.SetActive(true);。
  2. Resume() 会设置 Time.timeScale = 1f;,并调用 panel.SetActive(false);。
  3. 在 BallMachine.cs 中,在 Update() 里的空格键检查上方添加 if (Time.timeScale == 0f) return;。

按下“开始”,发球后暂停:球会悬在半空中。然后点击“检查”。

亲手试试

using UnityEngine;

public class PauseMenu : MonoBehaviour
{
    public GameObject panel;

    public void Pause()
    {
        // 暂停游戏时间并显示面板
    }

    public void Resume()
    {
        // 游戏时间恢复正常速度,隐藏面板
    }
}

打造真正的游戏中的所有课

自己练习: Unity 在线编辑器