在场景之间存储变量的理想方法是通过单例管理器类。通过创建一个用于存储持久性数据的类,并将该类设置为DoNotDestroyOnLoad()
,可以确保可以立即访问该类并在场景之间持久化。
您还有另一个选择是使用PlayerPrefs
该类。PlayerPrefs
旨在允许您在播放会话之间保存数据,但是它仍然是在场景之间保存数据的一种手段。
使用单例类和 DoNotDestroyOnLoad()
以下脚本创建一个持久性单例类。单例类是旨在仅同时运行一个实例的类。通过提供此类功能,我们可以安全地创建静态自引用,以便从任何地方访问该类。这意味着您可以使用直接访问该类DataManager.instance
,包括该类中的任何公共变量。
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);
}
}
您可以在下面看到正在运行的单例。请注意,一旦运行初始场景,DataManager对象就会从特定于场景的标题移到层次结构视图上的“ DontDestroyOnLoad”标题。
使用PlayerPrefs
课程
Unity有一个内置类来管理称为的基本持久性数据PlayerPrefs
。提交给该PlayerPrefs
文件的任何数据都将在游戏会话中持续存在,因此自然地,它能够在场景之间保留数据。
该PlayerPrefs
文件可以存储类型的变量string
,int
和float
。当我们将值插入PlayerPrefs
文件时,我们会提供一个额外string
的键。我们使用相同的键稍后从PlayerPref
文件中检索我们的值。
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();
}
}
请注意,在处理PlayerPrefs
文件时,我采取了其他预防措施:
- 我已将每个键另存为
private static string
。这使我可以保证我一直在使用正确的密钥,这意味着如果出于任何原因必须更改密钥,则无需确保更改所有对其的引用。
PlayerPrefs
写入文件后,将文件保存到磁盘。如果您未在播放会话之间实现数据持久性,则这可能不会有所作为。PlayerPrefs
会在正常应用程序关闭时保存到磁盘,但是如果您的游戏崩溃,它可能不会自然调用。
- 其实,我检查每个键存在的
PlayerPrefs
,之前我尝试检索与它相关联的值。这看起来似乎毫无意义的重复检查,但这是一个好习惯。
- 我有一种
Delete
立即擦除PlayerPrefs
文件的方法。如果您不打算在播放会话中包括数据持久性,则可以考虑在上调用此方法Awake
。通过清除PlayerPrefs
在每场比赛开始的文件,可以确保任何数据都与前一交易日坚持不误从数据处理当前会话。
您可以PlayerPrefs
在下面看到实际情况。请注意,当我单击“保存数据”时,我直接调用该Save
方法,而当我单击“加载数据”时,我直接调用了该Load
方法。您自己的实现可能会有所不同,但是它展示了基础知识。
最后一点,我要指出,您可以扩展basic PlayerPrefs
,以存储更多有用的类型。JPTheK9 为类似的问题提供了一个很好的答案,在该问题中,JPTheK9 提供了一个脚本,用于将数组序列化为字符串形式并存储在PlayerPrefs
文件中。他们还向我们指向Unify Community Wiki,用户在该PlayerPrefsX
站点上载了更广泛的脚本,以支持更多类型的向量,例如向量和数组。