当加载玩家数据时,任何高于400的数字都会被削减到319
本文关键字:数字 数据 玩家 加载 任何高 | 更新日期: 2023-09-27 18:12:54
我试图在Unity中保存和加载基本的玩家数据,但每当我加载游戏时,除了存储值大于400的内容外,所有内容都可以正常加载,并减少到319。例如,如果我存了200个硬币,它将加载200个硬币,但如果我存了500个硬币,它将加载319个硬币。
这是我用来保存的代码:public static void save() {
Debug.Log("Saving Player Data");
//Convert Player Data to String
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, playerData);
byte[] newData = ms.ToArray();
string newDataString = Encoding.ASCII.GetString(newData);
FileStream file = File.Create(Application.persistentDataPath + "/playerData.aaa");
bf.Serialize(file, newDataString);
file.Close();
}
下面是我用来加载的代码:
public static void load() {
playerData = new PlayerData();
if(File.Exists(Application.persistentDataPath + "/playerData.aaa")) {
try {
Debug.Log("Loading Player Data");
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/playerData.aaa", FileMode.Open);
string dataString = bf.Deserialize(file).ToString();
file.Close();
//Convert String to Player Data
byte[] playerDataBytes = Encoding.ASCII.GetBytes(dataString);
MemoryStream ms = new MemoryStream();
ms.Write(playerDataBytes, 0, playerDataBytes.Length);
ms.Seek(0, SeekOrigin.Begin);
playerData = (PlayerData)bf.Deserialize(ms);
} catch(Exception) {
Debug.Log("Messed Up Player Log: Creating New");
File.Delete(Application.persistentDataPath + "/playerData.aaa");
save();
}
} else {
Debug.Log("Player Data does not exist. Creating new and saving it");
save();
}
}
playerData是包含playerData的对象。它是可序列化的。
下面是playerData的代码:using System.IO;
[System.Serializable]
public class PlayerData{
public bool tutorialComplete = false;
public ArtStyle artPrefs = ArtStyle.ORIGINAL;
public int coins = 0;
public ShopItem brightTexturePack = new ShopItem("Bright", 5);
public ShopItem neonTexturePack = new ShopItem("Neon", 50);
public ShopItem paperTexturePack = new ShopItem("Paper", 500);
public ShopItem getShopItem(string itemName) {
switch(itemName) {
case "BRIGHT":
return brightTexturePack;
case "NEON":
return neonTexturePack;
case "PAPER":
return paperTexturePack;
}
return null;
}
}
[System.Serializable]
public class ShopItem {
public int price;
public string name;
public bool isBought = false;
public ShopItem(string name, int price) {
this.price = price;
this.name = name;
}
}
我唯一看到问题发生的地方是可变硬币和霓虹纹理包的价格,因为它们是唯一的变量,通常达到400以上。
我一直想弄清楚问题是什么,但整个问题对我来说根本没有意义。它总是将存储在playerData中的任何变量中的大于400的任何数字更改为319。
当您序列化您的对象时,int
字段正在被序列化-值400(十六进制的0x0190
)被序列化为两个字节:0x01
和0x90
。
但是,您正在使用ASCII编码和ASCII.GetString
状态的文档:
ASCIIEncoding不提供错误检测。任何大于十六进制0x7F的字节都被解码为Unicode问号("?")。
Unicode问号的值为0x3F
- 0x01
和0x90
的原始字节实际上被保存为0x01
和0x3F
。
猜猜十六进制数0x013F
的十进制是多少?
319 .
由于您使用ASCII.GetString
,任何高于383 (0x017F
)的数字将始终被序列化为319。
实际上,我刚刚意识到,任何具有大于0x7F
的低顺序字节值的数字都将使用您的序列化进行更改,因此尝试保存128个硬币将导致您的加载方法返回63个硬币的值。
你的问题是BinaryFormatter bf = new BinaryFormatter();
与Encoding.ASCII.GetString(newData);
相结合,你不能在你从序列化调用中获得的任意数据上调用GetString,你会看到丢失的数据,就像你得到的一样。
使用unity内置的JsonUtility类将您的类转换为字符串,而不是使用BinaryFormatter + GetString