Bha*_*kar 2 c# unity-game-engine
我试图在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();
}
Run Code Online (Sandbox Code Playgroud)
这是我用来加载的代码:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
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;
}
}
Run Code Online (Sandbox Code Playgroud)
我看到问题的唯一地方是变量硬币和霓虹纹理包的价格,因为它们是通常达到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个硬币.
研究保持对象的其他方法.
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |