Singleton
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 13 trên 60.
Một tham chiếu Inspector cần có thứ để kéo vào. Kẻ địch mà spawner tạo ra trong lúc chơi game xuất phát từ prefab, và prefab chỉ có thể tham chiếu đến asset và các thành phần của chính nó, không bao giờ đến một đối tượng trong scene, nên trường GameManager của chúng sẽ để trống. Cách giải quyết thường dùng là singleton: GameManager lưu chính nó vào một trường mà mọi script đều có thể truy cập thông qua tên lớp.
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
private int kills;
void Awake()
{
Instance = this;
}
public void EnemyDown()
{
kills++;
Debug.Log("Kills: " + kills);
}
}// Enemy.cs, trên prefab của kẻ địch
public void Die()
{
GameManager.Instance.EnemyDown();
Destroy(gameObject);
}static có nghĩa là trường đó thuộc về lớp, không phải một đối tượng. Mỗi đối tượng GameManager sẽ có kills riêng, nhưng trong cả game chỉ có một Instance, và bạn truy cập nó bằng tên lớp: GameManager.Instance. Mọi script đều có thể đọc nó, kể cả một kẻ địch vừa được tạo ra cách đây một phút, mà không cần điền trường riêng của nó.
Trình quản lý gán Instance = this; trong Awake, tại đó this là chính script đó. Unity chạy mọi Awake trong scene trước bất kỳ Start nào, vì vậy các script khác có thể dùng GameManager.Instance từ Start trở đi. Nếu có một GameManager thứ hai trong scene, nó sẽ ghi đè Instance bằng chính nó; chương Scenes and Levels sẽ chỉ cách ngăn điều đó.
Thử thách
DễĐể các thiên thạch liên hệ với GameManager thông qua một singleton.
- Trong
GameManager.cs, thêmpublic static GameManager Instance;và một hàmAwake()cóInstance = this;. - Trong
Meteor.cs, xóa trườnggamevà gọiGameManager.Instance.MeteorLanded()cùngGameManager.Instance.MeteorCaught()thay thế.
Nhấn Chơi và bắt một thiên thạch: Caught: 1 sẽ hiển thị, không có lỗi nào trong Console. Sau đó nhấn Kiểm tra.
Tự làm thử
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
public TMP_Text caughtText;
public TMP_Text shieldText;
private int caught;
private int shield = 3;
public void MeteorCaught()
{
caught++;
caughtText.text = "Caught: " + caught;
}
public void MeteorLanded()
{
shield--;
shieldText.text = "Shield: " + shield;
}
}
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