Một cách lý tưởng để lưu trữ các biến giữa các cảnh là thông qua lớp trình quản lý đơn. Bằng cách tạo một lớp để lưu trữ dữ liệu liên tục và đặt lớp đó thành DoNotDestroyOnLoad()
, bạn có thể đảm bảo nó có thể truy cập ngay lập tức và tồn tại giữa các cảnh.
Một lựa chọn khác bạn có là sử dụng PlayerPrefs
lớp. PlayerPrefs
được thiết kế để cho phép bạn lưu dữ liệu giữa các phiên phát , nhưng nó vẫn sẽ phục vụ như một phương tiện để lưu dữ liệu giữa các cảnh .
Sử dụng một lớp đơn và DoNotDestroyOnLoad()
Kịch bản sau đây tạo ra một lớp singleton liên tục. Một lớp singleton là một lớp được thiết kế để chỉ chạy một thể hiện cùng một lúc. Bằng cách cung cấp chức năng như vậy, chúng ta có thể tạo một tham chiếu tự tĩnh một cách an toàn, để truy cập lớp từ bất cứ đâu. Điều này có nghĩa là bạn có thể truy cập trực tiếp vào lớp DataManager.instance
, bao gồm mọi biến công khai trong lớp.
using UnityEngine;
/// <summary>Manages data for persistance between levels.</summary>
public class DataManager : MonoBehaviour
{
/// <summary>Static reference to the instance of our DataManager</summary>
public static DataManager instance;
/// <summary>The player's current score.</summary>
public int score;
/// <summary>The player's remaining health.</summary>
public int health;
/// <summary>The player's remaining lives.</summary>
public int lives;
/// <summary>Awake is called when the script instance is being loaded.</summary>
void Awake()
{
// If the instance reference has not been set, yet,
if (instance == null)
{
// Set this instance as the instance reference.
instance = this;
}
else if(instance != this)
{
// If the instance reference has already been set, and this is not the
// the instance reference, destroy this game object.
Destroy(gameObject);
}
// Do not destroy this object, when we load a new scene.
DontDestroyOnLoad(gameObject);
}
}
Bạn có thể thấy singleton trong hành động, dưới đây. Lưu ý rằng ngay khi tôi chạy cảnh ban đầu, đối tượng DataManager chuyển từ tiêu đề cụ thể của cảnh sang tiêu đề "DontDestroyOnLoad", trên chế độ xem phân cấp.
Sử dụng PlayerPrefs
lớp học
Unity có một lớp được xây dựng để quản lý dữ liệu liên tục cơ bản được gọiPlayerPrefs
. Bất kỳ dữ liệu nào được cam kết với PlayerPrefs
tệp sẽ tồn tại trong các phiên trò chơi , do đó, một cách tự nhiên, nó có khả năng duy trì dữ liệu qua các cảnh.
Các PlayerPrefs
tập tin có thể lưu trữ các biến của các loại string
, int
và float
. Khi chúng tôi chèn giá trị vào PlayerPrefs
tệp, chúng tôi cung cấp bổ sung string
làm khóa. Chúng tôi sử dụng cùng một khóa để sau đó lấy các giá trị của chúng tôi từ PlayerPref
tệp.
using UnityEngine;
/// <summary>Manages data for persistance between play sessions.</summary>
public class SaveManager : MonoBehaviour
{
/// <summary>The player's name.</summary>
public string playerName = "";
/// <summary>The player's score.</summary>
public int playerScore = 0;
/// <summary>The player's health value.</summary>
public float playerHealth = 0f;
/// <summary>Static record of the key for saving and loading playerName.</summary>
private static string playerNameKey = "PLAYER_NAME";
/// <summary>Static record of the key for saving and loading playerScore.</summary>
private static string playerScoreKey = "PLAYER_SCORE";
/// <summary>Static record of the key for saving and loading playerHealth.</summary>
private static string playerHealthKey = "PLAYER_HEALTH";
/// <summary>Saves playerName, playerScore and
/// playerHealth to the PlayerPrefs file.</summary>
public void Save()
{
// Set the values to the PlayerPrefs file using their corresponding keys.
PlayerPrefs.SetString(playerNameKey, playerName);
PlayerPrefs.SetInt(playerScoreKey, playerScore);
PlayerPrefs.SetFloat(playerHealthKey, playerHealth);
// Manually save the PlayerPrefs file to disk, in case we experience a crash
PlayerPrefs.Save();
}
/// <summary>Saves playerName, playerScore and playerHealth
// from the PlayerPrefs file.</summary>
public void Load()
{
// If the PlayerPrefs file currently has a value registered to the playerNameKey,
if (PlayerPrefs.HasKey(playerNameKey))
{
// load playerName from the PlayerPrefs file.
playerName = PlayerPrefs.GetString(playerNameKey);
}
// If the PlayerPrefs file currently has a value registered to the playerScoreKey,
if (PlayerPrefs.HasKey(playerScoreKey))
{
// load playerScore from the PlayerPrefs file.
playerScore = PlayerPrefs.GetInt(playerScoreKey);
}
// If the PlayerPrefs file currently has a value registered to the playerHealthKey,
if (PlayerPrefs.HasKey(playerHealthKey))
{
// load playerHealth from the PlayerPrefs file.
playerHealth = PlayerPrefs.GetFloat(playerHealthKey);
}
}
/// <summary>Deletes all values from the PlayerPrefs file.</summary>
public void Delete()
{
// Delete all values from the PlayerPrefs file.
PlayerPrefs.DeleteAll();
}
}
Lưu ý rằng tôi có biện pháp phòng ngừa bổ sung, khi xử lý PlayerPrefs
tệp:
- Tôi đã lưu từng khóa là a
private static string
. Điều này cho phép tôi đảm bảo tôi luôn sử dụng đúng khóa và điều đó có nghĩa là nếu tôi phải thay đổi khóa vì bất kỳ lý do gì, tôi không cần phải đảm bảo tôi thay đổi tất cả các tham chiếu đến nó.
- Tôi lưu
PlayerPrefs
tập tin vào đĩa sau khi ghi vào nó. Điều này có thể sẽ không tạo ra sự khác biệt, nếu bạn không thực hiện kiên trì dữ liệu qua các phiên chơi. PlayerPrefs
sẽ lưu vào đĩa trong khi đóng ứng dụng bình thường, nhưng nó có thể không tự nhiên gọi nếu trò chơi của bạn gặp sự cố.
- Tôi thực sự kiểm tra xem mỗi khóa tồn tại trong
PlayerPrefs
, trước khi tôi cố gắng truy xuất một giá trị được liên kết với nó. Điều này có vẻ như kiểm tra hai lần vô nghĩa, nhưng nó là một thực hành tốt để có.
- Tôi có một
Delete
phương pháp ngay lập tức xóa PlayerPrefs
tập tin. Nếu bạn không có ý định bao gồm dữ liệu kiên trì trong các phiên chơi, bạn có thể cân nhắc gọi phương thức này vào Awake
. Bằng cách xóa các PlayerPrefs
tập tin khi bắt đầu mỗi trận đấu, bạn đảm bảo rằng bất kỳ dữ liệu đã tồn tại so với phiên trước không được nhầm lẫn xử lý như dữ liệu từ hiện tại phiên làm việc.
Bạn có thể thấy PlayerPrefs
trong hành động, dưới đây. Lưu ý rằng khi tôi nhấp vào "Lưu dữ liệu", tôi đang gọi trực tiếp Save
phương thức và khi tôi nhấp vào "Tải dữ liệu", tôi đang gọi trực tiếp Load
phương thức. Việc thực hiện của riêng bạn có thể sẽ khác nhau, nhưng nó thể hiện những điều cơ bản.
Như một lưu ý cuối cùng, tôi nên chỉ ra rằng bạn có thể mở rộng dựa trên cơ bản PlayerPrefs
, để lưu trữ các loại hữu ích hơn. JPTheK9 cung cấp một câu trả lời tốt cho một câu hỏi tương tự , trong đó họ cung cấp một tập lệnh để sắp xếp các mảng thành dạng chuỗi, được lưu trữ trong một PlayerPrefs
tệp. Họ cũng chỉ cho chúng tôi đến Unify Community Wiki , nơi người dùng đã tải lên một PlayerPrefsX
tập lệnh mở rộng hơn để cho phép hỗ trợ nhiều loại hơn, chẳng hạn như vectơ và mảng.