如何管理 save/load 的数百个变量
How to manage save/load of hundreds of variables
我正在 Unity 中制作角色扮演游戏。仍然很新,所以我遵循了 their 创建 save/load 功能的教程。
在本教程中,他们使用了 2 个变量,并且效果很好。
但是我想创建一个带有沙盒的大型游戏。这意味着我需要保存所有东西在我的世界中的位置,除此之外我还需要很多玩家统计数据、可解锁项、任务、NPC 进度等等。
到目前为止,我有一个 saving/loading 我的球员初始统计数据的有效实施,仅此一项就产生了很多:
DataManager
public class DataManager : MonoBehaviour {
private string saveLocation = "/data.dat";
public static DataManager manager;
//PLAYER
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int [] toLevelUp;
void Awake(){
if (manager == null) {
DontDestroyOnLoad (gameObject);
manager = this;
} else if (manager != this) {
Destroy (gameObject);
}
}
public void Save(){
Debug.Log ("Saving");
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Create (Application.persistentDataPath + saveLocation);
PlayerData playerData = new PlayerData (maxHealth, currentHealth, currentLevel, currentExp, toLevelUp);
bf.Serialize (file, playerData);
file.Close ();
}
public void Load(){
Debug.Log ("Loading");
if (File.Exists (Application.persistentDataPath + saveLocation)) {
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Open (Application.persistentDataPath + saveLocation, FileMode.Open);
PlayerData playerData = (PlayerData)bf.Deserialize (file);
file.Close ();
maxHealth = playerData.maxHealth;
currentHealth = playerData.currentHealth;
currentLevel = playerData.currentLevel;
currentExp = playerData.currentExp;
toLevelUp = playerData.toLevelUp;
}
}
}
玩家数据
[System.Serializable]
public class PlayerData {
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int [] toLevelUp;
public PlayerData(int maxHealth, int currentHealth, int currentLevel, int currentExp, int [] toLevelUp){
this.maxHealth = maxHealth;
this.currentHealth = currentHealth;
this.currentLevel = currentLevel;
this.currentExp = currentExp;
this.toLevelUp = toLevelUp;
}
}
这根本就不是可扩展的。是否有人具有使用任何 advice/code 样本对大量变量实施 save/load 的经验?一定有更好的办法吧?
编辑:
新数据管理器:
public class DataManager : MonoBehaviour {
private string saveLocation = "/data.dat";
public static DataManager manager;
//PLAYER
public PlayerData playerData = new PlayerData ();
void Awake(){
if (manager == null) {
DontDestroyOnLoad (gameObject);
manager = this;
} else if (manager != this) {
Destroy (gameObject);
}
}
public void Save(){
Debug.Log ("Saving");
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Create (Application.persistentDataPath + saveLocation);
bf.Serialize (file, playerData);
file.Close ();
}
public void Load(){
Debug.Log ("Loading");
if (File.Exists (Application.persistentDataPath + saveLocation)) {
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Open (Application.persistentDataPath + saveLocation, FileMode.Open);
PlayerData pd = (PlayerData)bf.Deserialize (file);
file.Close ();
playerData = pd;
}
}
}
您不必每次都创建新的 PlayerData 来保存它。您不必像在构造函数中那样复制它。创建一个 PlayerData 实例,然后在您的游戏中使用它。就是这样。删除那些局部变量,因为它们已经在 PlayerData
class 中。
不要这样做:
[System.Serializable]
public class PlayerData
{
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int[] toLevelUp;
}
//Why Why would you need these again?
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int[] toLevelUp;
private string saveLocation = "/data.dat";
//PLAYER
public PlayerData playerData = new PlayerData();
public void Save()
{
if (File.Exists(Application.persistentDataPath + saveLocation))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + saveLocation, FileMode.Open);
PlayerData playerData = (PlayerData)bf.Deserialize(file);
file.Close();
//Whyyyyyyyyyyyy Don't do this
maxHealth = playerData.maxHealth;
currentHealth = playerData.currentHealth;
currentLevel = playerData.currentLevel;
currentExp = playerData.currentExp;
toLevelUp = playerData.toLevelUp;
}
}
请注意您是如何重新定义 maxHealth
、currentHealth
、currentLevel
、currentExp
和 toLevelUp
变量的。完全没有必要。
这样做:
[System.Serializable]
public class PlayerData
{
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int[] toLevelUp;
}
string saveLocation = "/data.dat";
//Make the PlayerData data part of your game
PlayerData playerData;
void Start()
{
playerData = new PlayerData();
playerData.maxHealth = 100;
playerData.currentLevel = 1;
playerData.currentHealth = 50;
}
public void Save(PlayerData pData)
{
UnityEngine.Debug.Log("Saving");
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath + saveLocation);
bf.Serialize(file, pData);
file.Close();
}
想保存的时候调用Save(playerData);
即可。
注意如何不需要复制数据或执行 PlayerData playerData = new PlayerData (maxHealth, currentHealth, currentLevel, currentExp, toLevelUp);
。只需保存您已经在游戏中使用的实例。
最后,使用 ,您可以在一行中完成此操作 DataSaver.saveData(playerData, "players");
我正在 Unity 中制作角色扮演游戏。仍然很新,所以我遵循了 their 创建 save/load 功能的教程。
在本教程中,他们使用了 2 个变量,并且效果很好。 但是我想创建一个带有沙盒的大型游戏。这意味着我需要保存所有东西在我的世界中的位置,除此之外我还需要很多玩家统计数据、可解锁项、任务、NPC 进度等等。
到目前为止,我有一个 saving/loading 我的球员初始统计数据的有效实施,仅此一项就产生了很多:
DataManager
public class DataManager : MonoBehaviour {
private string saveLocation = "/data.dat";
public static DataManager manager;
//PLAYER
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int [] toLevelUp;
void Awake(){
if (manager == null) {
DontDestroyOnLoad (gameObject);
manager = this;
} else if (manager != this) {
Destroy (gameObject);
}
}
public void Save(){
Debug.Log ("Saving");
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Create (Application.persistentDataPath + saveLocation);
PlayerData playerData = new PlayerData (maxHealth, currentHealth, currentLevel, currentExp, toLevelUp);
bf.Serialize (file, playerData);
file.Close ();
}
public void Load(){
Debug.Log ("Loading");
if (File.Exists (Application.persistentDataPath + saveLocation)) {
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Open (Application.persistentDataPath + saveLocation, FileMode.Open);
PlayerData playerData = (PlayerData)bf.Deserialize (file);
file.Close ();
maxHealth = playerData.maxHealth;
currentHealth = playerData.currentHealth;
currentLevel = playerData.currentLevel;
currentExp = playerData.currentExp;
toLevelUp = playerData.toLevelUp;
}
}
}
玩家数据
[System.Serializable]
public class PlayerData {
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int [] toLevelUp;
public PlayerData(int maxHealth, int currentHealth, int currentLevel, int currentExp, int [] toLevelUp){
this.maxHealth = maxHealth;
this.currentHealth = currentHealth;
this.currentLevel = currentLevel;
this.currentExp = currentExp;
this.toLevelUp = toLevelUp;
}
}
这根本就不是可扩展的。是否有人具有使用任何 advice/code 样本对大量变量实施 save/load 的经验?一定有更好的办法吧?
编辑:
新数据管理器:
public class DataManager : MonoBehaviour {
private string saveLocation = "/data.dat";
public static DataManager manager;
//PLAYER
public PlayerData playerData = new PlayerData ();
void Awake(){
if (manager == null) {
DontDestroyOnLoad (gameObject);
manager = this;
} else if (manager != this) {
Destroy (gameObject);
}
}
public void Save(){
Debug.Log ("Saving");
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Create (Application.persistentDataPath + saveLocation);
bf.Serialize (file, playerData);
file.Close ();
}
public void Load(){
Debug.Log ("Loading");
if (File.Exists (Application.persistentDataPath + saveLocation)) {
BinaryFormatter bf = new BinaryFormatter ();
FileStream file = File.Open (Application.persistentDataPath + saveLocation, FileMode.Open);
PlayerData pd = (PlayerData)bf.Deserialize (file);
file.Close ();
playerData = pd;
}
}
}
您不必每次都创建新的 PlayerData 来保存它。您不必像在构造函数中那样复制它。创建一个 PlayerData 实例,然后在您的游戏中使用它。就是这样。删除那些局部变量,因为它们已经在 PlayerData
class 中。
不要这样做:
[System.Serializable]
public class PlayerData
{
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int[] toLevelUp;
}
//Why Why would you need these again?
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int[] toLevelUp;
private string saveLocation = "/data.dat";
//PLAYER
public PlayerData playerData = new PlayerData();
public void Save()
{
if (File.Exists(Application.persistentDataPath + saveLocation))
{
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + saveLocation, FileMode.Open);
PlayerData playerData = (PlayerData)bf.Deserialize(file);
file.Close();
//Whyyyyyyyyyyyy Don't do this
maxHealth = playerData.maxHealth;
currentHealth = playerData.currentHealth;
currentLevel = playerData.currentLevel;
currentExp = playerData.currentExp;
toLevelUp = playerData.toLevelUp;
}
}
请注意您是如何重新定义 maxHealth
、currentHealth
、currentLevel
、currentExp
和 toLevelUp
变量的。完全没有必要。
这样做:
[System.Serializable]
public class PlayerData
{
public int maxHealth;
public int currentHealth;
public int currentLevel;
public int currentExp;
public int[] toLevelUp;
}
string saveLocation = "/data.dat";
//Make the PlayerData data part of your game
PlayerData playerData;
void Start()
{
playerData = new PlayerData();
playerData.maxHealth = 100;
playerData.currentLevel = 1;
playerData.currentHealth = 50;
}
public void Save(PlayerData pData)
{
UnityEngine.Debug.Log("Saving");
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath + saveLocation);
bf.Serialize(file, pData);
file.Close();
}
想保存的时候调用Save(playerData);
即可。
注意如何不需要复制数据或执行 PlayerData playerData = new PlayerData (maxHealth, currentHealth, currentLevel, currentExp, toLevelUp);
。只需保存您已经在游戏中使用的实例。
最后,使用 DataSaver.saveData(playerData, "players");