【发布时间】:2021-07-03 00:45:59
【问题描述】:
我是 stackoverflow 和 Unity3D 的新手,如果我做错了,我很抱歉。
所以目前,我正在制作一款益智游戏。它有50个不同的级别。 我需要为他们每个人保存 3 或 4 个变量。 例如,当级别 1 被清除时,我希望它存储 (int)hitCounts、(bool)cleared、(int)bestHitCounts。 我不想使用 playerPrefs,因为我不希望它可以从盒子外面读取。我希望将其转换为二进制文件。 这是我所拥有的:
#1 : 制作了一个静态类 TGameDat
[System.Serializable]
public class TGameDat
{
public int tGameDatInt;
public bool tGameDatBool;
public int tSceneIndex;
public TGameDat (TPlayer player)
{
tGameDatInt = player.tInt;
tGameDatBool = player.tBool;
tSceneIndex = player.tScene;
}
}
#2 : 然后制作 Tplayer(monobehaviour)
public class TPlayer : MonoBehaviour
{
public int tInt = 0;
public bool tBool = false;
public int tScene;
public List<TPlayer> TestGameDatList = new List<TPlayer>();
private void Start()
{
TSceneMaker();
}
public void TSceneMaker()
{
tScene = SceneManager.GetActiveScene().buildIndex;
}
public void TNextScene()
{
SceneManager.LoadScene(tScene + 1);
}
public void TPreviousScene()
{
SceneManager.LoadScene(tScene - 1);
}
public void TSaveVariables()
{
TSave.TSavePlayer(this);
TestGameDatList.Add(this);
Debug.Log("saved");
Debug.Log(tInt + " " + tBool + " " + tScene);
}
public void TLoadVariables()
{
List<TGameDat> data = TSave.TLoadPlayer(this);
Debug.Log("loaded. data count = " + data.Count + " tSceneIndex " + tScene);
tInt = data[0].tGameDatInt;
tBool = data[0].tGameDatBool;
tScene = data[0].tSceneIndex;
}
}
#3:最后我创建了一个保存和加载系统:
public static class TSave
{
public static void TSavePlayer (TPlayer player)
{
BinaryFormatter formatter = new BinaryFormatter();
List<TGameDat> data = new List<TGameDat>();
string path = Application.persistentDataPath + "/Tsave_" + player.tScene + ".fun";
if(File.Exists(path))
{
FileStream stream = File.Open(path, FileMode.Open);
data.Add(new TGameDat(player));
formatter.Serialize(stream, data);
stream.Close();
}
else
{
FileStream stream = File.Create(path);
data.Add(new TGameDat(player));
formatter.Serialize(stream, data);
stream.Close();
}
}
public static List<TGameDat> TLoadPlayer(TPlayer player)
{
string path = Application.persistentDataPath + "/Tsave_" + player.tScene + ".fun";
if(File.Exists(path))
{
BinaryFormatter formatter = new BinaryFormatter();
FileStream stream = File.Open(path, FileMode.Open);
List<TGameDat> data = new List<TGameDat>();
data = formatter.Deserialize(stream) as List<TGameDat>;
stream.Close();
return data;
}
else
{
Debug.LogError("Save file not found in " + path);
return null;
}
}
}
所以,这是我的问题:
1:当前情况下,每个场景编译一个二进制文件。所以最后会堆一堆二进制文件……好像50个,我有50个场景……是不是太多了?
2 : 当然我尝试了使用 List 制作单个保存文件,每个级别都会在其中添加自己的变量数据。 但它不会添加数据,而是简单地替换以前的数据。那么 List 中总是只有 1 个索引。 因此,当我加载时,变量来自上次播放的关卡!而当我在玩完第一个关卡后尝试玩另一个关卡时,因为列表中只有一个索引,我得到了超出范围的错误。
我该如何处理? 很抱歉很长的文字!
感谢您的投入!
【问题讨论】:
-
windows中的文件不能以读写方式打开。所以在阅读现有文件后关闭。然后将新播放器添加到您的 c# 类并再次打开文件以保存新的序列化数据。
-
您可以使用
PlayerPrefs并对值进行加密以确保安全。 -
@jdweng :是的,我明白了,这就是我在 TSave 类中打开和关闭文件的原因。并且在每个关卡中,都附加了TPlayer,并调用了TSavePlayer 或TLoadPlayer,并且每次都打开和关闭,至少这是我试图做的,不是吗?还是有什么我没看到的?
-
@Yaroslav :真的吗?如何?你拿 PlayerPrefs 文件,然后像我在这里做的那样在二进制文件中加密?你能指点我的指南或示例代码吗?
-
查看方法 TSavePlayer(IF/Else 代码)
标签: c# unity3d save load binaryfiles