Sự kiện vòng đời: từ lúc trận bắt đầu đến khi kết thúc
Mục lục
Kịch bản Craftland phản ứng theo sự kiện. Hiểu thứ tự các sự kiện quan trọng là nền tảng để map chạy đúng. Bài này gom những sự kiện dùng nhiều nhất theo "đời sống" của một trận đấu.
1. Đời sống của một thực thể
event OnAwake()
event OnEnable()
event OnDisable()
event OnDestroy()
- Khi Thực thể được tạo (
OnAwake) — chỗ hợp lý để khởi tạo giá trị ban đầu. - Khi Thực thể có sẵn / không khả dụng (
OnEnable/OnDisable) — đi cặp với khốiSetActive(bật/tắt thực thể). - Khi thực thể bị phá hủy (
OnDestroy) — dọn dẹp, ví dụ gỡ thực thể khỏi danh sách bạn đang theo dõi.
2. Nhịp cập nhật
event OnUpdate()
event OnLateUpdate()
event OnFixedUpdate()
Ba sự kiện này chạy lặp đi lặp lại trong suốt trận. Quy tắc an toàn: đừng đặt việc nặng vào đây (duyệt toàn bộ người chơi, tạo thực thể…) vì nó chạy rất nhiều lần. Việc theo chu kỳ vài giây nên dùng vòng lặp với WaitForMillisecond thay vì đếm khung hình. Module Thời gian trận đấu có PauseFixedUpdate / ResumeFixedUpdate để tạm dừng nhịp cố định.
3. Người chơi vào, ra, kết nối lại
event OnPlayerJoin(player entity<Player>)
event OnPlayerQuit(player entity<Player>)
event OnDisconnect(player entity<Player>)
event OnReconnect(player entity<Player>)
Mỗi sự kiện đưa sẵn tham số player — chính người chơi vừa tham gia/thoát. Ví dụ minh hoạ khi có người vào trận:
// Minh hoạ theo chữ ký — trong Studio lắp bằng khối cùng tên
event OnPlayerJoin(player entity<Player>)
LogInfo(player) // In thông báo để kiểm tra khi thử map
JoinNewTeam(player, out var team, out var status)
Đừng quên OnReconnect: người rớt mạng quay lại có thể cần được khôi phục trạng thái (đội, vị trí, điểm) mà bạn đã gán lúc đầu.
4. Vòng đấu và giai đoạn
event OnRoundStart(roundIndex int)
event OnRoundEnd(roundIndex int)
event OnPhaseStart(phase entity<Phase>)
event OnPhaseEnd(phase entity<Phase>)
func SwitchPhase(phaseIndex int)
func EndCurrentPhase()
Module Quy trình công việc chỉ có 2 API nhưng là "xương sống" của map nhiều màn: chia trận thành các giai đoạn (chuẩn bị → thi đấu → tổng kết), dùng SwitchPhase hoặc EndCurrentPhase để chuyển, và lắng nghe OnPhaseStart/OnPhaseEnd để bật/tắt luật tương ứng.
5. Kết thúc trận
event OnGameEnd()
event OnUserQuitOrUserMatchEnd(player entity<Player>)
func UploadGameResult(target entity<Player>, result GameResultType, scoreName List<string>, score List<string>)
UploadGameResult gửi kết quả của từng người chơi, với hai danh sách song song: tên chỉ số và giá trị. Lưu ý toàn bộ API cũ trong module Kết quả trận đấu hiện đã bị đánh dấu hết hạn.
6. Tự tạo sự kiện riêng
func DispatchEvent(eventID EventID, target entity, params List<object>)
func BroadcastCustomEvent(eventID EventID, platform PlatformType, params List<object>)
Khi nhiều kịch bản cần "nói chuyện" với nhau (VD: nút bấm mở cửa ở nơi khác), hãy gửi sự kiện tuỳ chỉnh thay vì để các kịch bản đọc biến của nhau — dễ bảo trì hơn nhiều.