Máy trạng thái
Thuộc phần Kiến trúc trò chơi trong Unity trong hành trình Unity của Coddy. Bài học 37 trên 64.
Phương thức SetState của Beacon sẽ giống nhau trong mọi đối tượng có các trạng thái: tháp pháo, kẻ địch, cánh cửa. Đoạn code đó có thể nằm trong một lớp riêng, máy trạng thái, giữ trạng thái hiện tại và thay đổi trạng thái đó. Mỗi đối tượng tạo một máy trạng thái và gọi máy đó, thay vì lặp lại đoạn code:
public class StateMachine
{
public IState Current { get; private set; }
public void ChangeState(IState next)
{
Current?.Exit();
Current = next;
Current.Enter();
}
public void Tick()
{
Current?.Tick();
}
}
public class Beacon : MonoBehaviour
{
public Renderer lamp;
private StateMachine machine = new StateMachine();
private IState blink;
private IState steady;
void Start()
{
blink = new BlinkState(lamp);
steady = new SteadyState();
machine.ChangeState(steady);
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame) machine.ChangeState(machine.Current == steady ? blink : steady);
machine.Tick();
}
}Lần gọi ChangeState đầu tiên không có trạng thái nào để thoát: Current là null, và ?. bỏ qua lời gọi Exit. Phần 1 đã lưu ý rằng ?. không phát hiện được giá trị null giả của Unity; điều đó áp dụng cho các đối tượng Unity đã bị hủy, còn các trạng thái là đối tượng C# thông thường, nên ?. an toàn ở đây. Current có private set, nên không script nào có thể đổi trạng thái nếu không thông qua ChangeState cùng Exit và Enter.
Thứ tự bên trong ChangeState rất quan trọng mỗi khi hai trạng thái tác động lên cùng một thứ. Exit hoàn tác những gì trạng thái cũ đã thay đổi, sau đó Enter thiết lập trạng thái mới, nên trạng thái mới có quyền quyết định cuối cùng. Nếu Enter của DarkState tắt đèn và chạy trước Exit của BlinkState, thì Exit đó sẽ bật đèn trở lại trong trạng thái tối. StateMachine cũng là một lớp thông thường: đèn hiệu, tháp pháo và kẻ địch mỗi đối tượng tạo máy trạng thái riêng bằng new và gọi Tick từ Update.
Thử thách
Trung bìnhChạy các trạng thái sẵn sàng của người chơi bằng một máy trạng thái.
- Trong
StateMachine.cs, viếtpublic class StateMachinevớipublic IState Current { get; private set; }và một phương thứcTick()để cập nhật trạng thái. ChangeState(IState next)bỏ qua trạng thái hiện tại; nếu không, gọi Exit, gánCurrent, rồi gọi Enter.Player: Start tạomachine,walk,sneakvà chuyển sang trạng thái đi bộ; Update chuyển sang trạng thái rón rén khi bạn giữ Space, nếu không thì chuyển sang trạng thái đi bộ, rồi cập nhật trạng thái.
Nhấn Chơi và giữ Space: Sneak: enter. Sau đó nhấn Kiểm tra.
Tự làm thử
// StateMachine: Current, ChangeState và Tick
Tất cả bài học trong Kiến trúc trò chơi trong Unity
1Thành phần, không phải hệ thống phân cấp
Thành phần nhỏTập lệnh kẻ địch cơ sởThành phần trừu tượngCác thành phần phối hợp với nhauÔn tập: tháp pháo mô-đunÔn tập: pháo nòng đôi4Dữ liệu tuần tự hóa
Lớp có thể tuần tự hóaDanh sách trong InspectorKiểu liệt kê trong InspectorÔn tập: Bảng vật phẩm rơiÔn tập: Quay vật phẩm2Giao diện trong Unity
IDamageableGiao diện và TryGetComponentGetComponentsÔn tập: phím tương tácÔn tập: đối tượng gần nhất trong tầm với5ScriptableObjects
Tài sản dữ liệuChỉ số vũ khíCài đặt dùng chungLưu gióSóng dưới dạng dữ liệuÔn tập: Cơ sở dữ liệu vật phẩmÔn tập: Mua hàng từ cửa hàng8Code có thể tái sử dụng
Phương thức mở rộngSingleton tổng quátCác hàm hỗ trợ tổng quátÔn tập: FindNearest3Sự kiện
Sự kiện C# trong UnityĐăng ký trong OnEnableCác trường UnityEventSự kiện điều khiển UIÔn tập: Cửa sổ bật lên thành tíchÔn tập: Bộ hẹn giờ cửa sổ bật lên6Lưu dữ liệu bằng JSON
JsonUtilityLưu trò chơiTải dữ liệu và giá trị mặc địnhÔn tập: các ô lưuChọn và xóa một ô lưu9Tái sử dụng đối tượng bằng pool
Vì sao cần pool đối tượngPool dùng hàng đợiObjectPool của UnityÔn tập: pool đạnTự luyện tập: Playground Unity