Menu
CoddyTech

Tạm dừng bằng timeScale

Thuộc phần Xây dựng trò chơi thực tế trong hành trình Unity của Coddy. Bài học 34 trên 60.

Time.timeScale điều khiển tốc độ thời gian trong game: 1 là tốc độ bình thường, còn 0 thì dừng thời gian. Khi giá trị là 0, Time.deltaTime cũng bằng 0, vì vậy mọi chuyển động được viết dưới dạng speed * Time.deltaTime đều dừng lại. FixedUpdate() không còn được gọi, nên các Rigidbody sẽ lơ lửng giữa không trung; WaitForSeconds và Invoke cũng phải chờ vì chúng tính thời gian trong game. Script này bật hoặc tắt trạng thái tạm dừng bằng một nút có danh sách On Click gọi TogglePause, đồng thời hiển thị một bảng khi game tạm dừng:

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

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

Không phải mọi thứ đều dừng lại. Update() và LateUpdate() vẫn được gọi mỗi khung hình, với Time.deltaTime bằng 0. yield return null trong coroutine vẫn tiếp tục ở khung hình tiếp theo, và giao diện vẫn nhận thao tác nhấp, nhờ đó nút có thể kết thúc trạng thái tạm dừng. Các phím vẫn được đọc: nếu nhấn Space để khiến một chú ếch nhảy trong Update(), chú ếch sẽ ghi nhận lần nhấn đó trong lúc tạm dừng và nhảy lên ở bước vật lý đầu tiên sau khi tiếp tục. Script của chú ếch bỏ qua các phím khi thời gian đang dừng:

void Update()
{
    if (Time.timeScale == 0f) return;   // đã tạm dừng: bỏ qua các phím
    if (Input.GetKeyDown(KeyCode.Space))
    {
        rb.AddForce(Vector3.up * jump, ForceMode.Impulse);
    }
}

Time.timeScale áp dụng cho toàn bộ game, không chỉ một cảnh: nếu tải cảnh khác khi giá trị này là 0, cảnh mới cũng sẽ bắt đầu ở trạng thái tạm dừng. Nút trong menu dùng để khởi động lại hoặc thoát khỏi một màn chơi sẽ đặt giá trị này về 1 trước.

challenge icon

Thử thách

Trung bình

Thêm menu tạm dừng cho sân tennis. Cảnh kết nối các nút Tạm dừng và Tiếp tục.

  1. Trong PauseMenu.cs, Pause() đặt Time.timeScale = 0f; và gọi panel.SetActive(true);.
  2. Resume() đặt Time.timeScale = 1f; và gọi panel.SetActive(false);.
  3. Trong BallMachine.cs, thêm if (Time.timeScale == 0f) return; phía trên phần kiểm tra phím Space trong Update().

Nhấn Chơi, giao bóng rồi tạm dừng: bóng sẽ đứng giữa không trung. Sau đó nhấn Kiểm tra.

Tự làm thử

using UnityEngine;

public class PauseMenu : MonoBehaviour
{
    public GameObject panel;

    public void Pause()
    {
        // Dừng thời gian trong trò chơi và hiển thị bảng điều khiển
    }

    public void Resume()
    {
        // Cho thời gian trong trò chơi chạy lại bình thường và ẩn bảng điều khiển
    }
}

Tất cả bài học trong Xây dựng trò chơi thực tế

Tự luyện tập: Playground Unity