使用 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。
挑战
中等为网球场添加暂停菜单。场景已连接“暂停”和“继续”按钮。
- 在
PauseMenu.cs中,Pause()会设置Time.timeScale = 0f;,并调用panel.SetActive(true);。 Resume()会设置Time.timeScale = 1f;,并调用panel.SetActive(false);。- 在
BallMachine.cs中,在Update()里的空格键检查上方添加if (Time.timeScale == 0f) return;。
按下“开始”,发球后暂停:球会悬在半空中。然后点击“检查”。
亲手试试
using UnityEngine;
public class PauseMenu : MonoBehaviour
{
public GameObject panel;
public void Pause()
{
// 暂停游戏时间并显示面板
}
public void Resume()
{
// 游戏时间恢复正常速度,隐藏面板
}
}
打造真正的游戏中的所有课
自己练习: Unity 在线编辑器