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.
Thử thách
DễTạo cuộc đua bấm phím trong 5 giây.
- Trong
SetState, chỉ hiển thị bảng của trạng thái mới. Khi chuyển sang Playing, đặttaps = 0,timeLeft = roundTimevàTaps: 0; khi chuyển sang GameOver, hiển thịTaps: 3trongresultText. - Trong
Update(), dùngswitch (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 trongtapsvàtapsTextcho đế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ế
1Văn bản trên màn hình
Canvas và văn bảnHiển thị điểm sốĐịnh dạng sốĐồng hồ đếm ngượcÔn tập: Đồng hồ tốc độ7Điều khiển thời gian
Tạm dừng bằng timeScaleChuyển động chậmThời gian không bị co giãnÔn tập: Bullet Time2Nút bấm và màn hình
Nút bấm và onClickLambdaKết nối trong InspectorBật và tắt bảngThanh máuÔn tập: Cửa hàng nâng cấp5Lưu dữ liệu với PlayerPrefs
Lưu một sốTải với giá trị mặc địnhĐiểm cao nhấtLưu cài đặtÔn tập: Tiền xu trong ngân hàng3Trình quản lý trò chơi
Một script chạy trò chơiSingletonCác trạng thái trò chơiChuyển đổi trạng tháiÔn tập: Trình quản lý vòng chơiTự luyện tập: Playground Unity