Menu
CoddyTech

Chuyển đổi trạng thái

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 15 trên 60.

Mỗi trạng thái của trò chơi thực hiện công việc khác nhau trong mỗi khung hình. Câu lệnh switch dựa trên trường trạng thái gom công việc vào một nhánh cho mỗi trạng thái, và mỗi khung hình chỉ chạy đúng một nhánh. Việc đổi trạng thái luôn thông qua một phương thức, nhờ đó màn hình luôn khớp với trạng thái. Trận đấu trùm này có phần mở đầu, trận chiến và màn hình chiến thắng:

public enum Phase { Intro, Fight, Won }

public class BossFight : MonoBehaviour
{
    public GameObject introPanel;
    public GameObject fightPanel;
    public GameObject winPanel;
    public int bossHp = 10;
    private Phase phase;
    private float timer = 3f;

    void Start()
    {
        Enter(Phase.Intro);
    }

    void Update()
    {
        switch (phase)
        {
            case Phase.Intro:
                timer -= Time.deltaTime;
                if (timer <= 0f) Enter(Phase.Fight);
                break;
            case Phase.Fight:
                if (bossHp <= 0) Enter(Phase.Won);
                break;
            case Phase.Won:
                break;
        }
    }

    void Enter(Phase next)
    {
        phase = next;
        introPanel.SetActive(next == Phase.Intro);
        fightPanel.SetActive(next == Phase.Fight);
        winPanel.SetActive(next == Phase.Won);
    }
}

Mỗi nhánh kết thúc bằng break, vì C# không biên dịch nếu một nhánh tiếp tục chạy sang nhánh kế tiếp. Khi bộ đếm thời gian của phần mở đầu kết thúc, Enter(Phase.Fight) đổi giai đoạn, nhưng nhánh Fight chỉ chạy ở khung hình tiếp theo, vì khung hình hiện tại đã chọn nhánh để chạy. Nếu dùng các khối if riêng biệt nối tiếp nhau, một khung hình có thể bắt đầu trận chiến và chạy code chiến đấu ngay trong cùng khung hình đó.

Enter là nơi duy nhất thay đổi phase. next == Phase.Fight chỉ có giá trị true đối với bảng chiến đấu, vì vậy một lần gọi sẽ hiển thị bảng đó và ẩn hai bảng còn lại. Những việc cần thực hiện khi vào một trạng thái, chẳng hạn như đặt lại bộ đếm thời gian, cũng được đặt trong Enter và chỉ chạy một lần thay vì chạy trong mỗi khung hình.

challenge icon

Thử thách

Dễ

Tạo cuộc đua bấm phím trong 5 giây.

  1. Trong SetState, chỉ hiển thị bảng của trạng thái mới. Khi chuyển sang Playing, đặt taps = 0, timeLeft = roundTime và Taps: 0; khi chuyển sang GameOver, hiển thị Taps: 3 trong resultText.
  2. Trong Update(), dùng switch (state): phím Space chuyển Ready sang Playing và GameOver sang Ready; ở trạng thái Playing, đếm mỗi lần nhấn Space trong taps và tapsText cho đến khi hết giờ.

Nhấn Chơi và đua hai lần. Sau đó nhấn Kiểm tra.

Tự làm thử

using UnityEngine;
using TMPro;

public enum GameState { Ready, Playing, GameOver }

public class GameManager : MonoBehaviour
{
    public GameObject readyPanel;
    public GameObject playPanel;
    public GameObject gameOverPanel;
    public TMP_Text tapsText;
    public TMP_Text resultText;
    public float roundTime = 5f;
    public GameState state;
    private int taps;
    private float timeLeft;

    void Start()
    {
        SetState(GameState.Ready);
    }

    void Update()
    {
        // Chuyển theo state:
        // Ready: Space bắt đầu một lượt chơi
        // Playing: Space tính một lần nhấn; hết thời gian thì trò chơi kết thúc
        // GameOver: Space quay lại Ready
    }

    void SetState(GameState next)
    {
        state = next;
        // Chỉ hiển thị bảng của trạng thái mới
        // Lượt chơi mới bắt đầu với 0 lần nhấn và kéo dài roundTime giây; khi kết thúc, resultText hiển thị số lần nhấ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