我正在尝试序列化我的整数但是我收到以下错误:
InvalidCastException:无法从源类型转换为目标类型。
SaveLoad.Load()
(在Assets / SaveLoad.cs:24处)引用另一个
只需在唤醒时加载它的脚本loadgame.Awake()
(at
Assets / loadgame.cs:8)指的是
StatContainer.totalcoins = (int)bf.Deserialize(file);
我是数据序列化的新手,有人可以解释我的错误在哪里吗?
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public static class SaveLoad {
//public static List<StatContainer> savedGames = new List<StatContainer>();
//it's static so we can call it from anywhere
public static void Save() {
//SaveLoad.savedGames.Add(StatContainer.current);
BinaryFormatter bf = new BinaryFormatter();
//Application.persistentDataPath is a string, so if you wanted you can put that into debug.log if you want to know where save games are located
FileStream file = File.Create (Application.persistentDataPath + "/savedGames.gd"); //you can call it anything you want
bf.Serialize(file, StatContainer.current);
file.Close();
}
public static void Load() {
if(File.Exists(Application.persistentDataPath + "/savedGames.gd")) {
BinaryFormatter bf = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/savedGames.gd", FileMode.Open);
StatContainer.totalcoins = (int)bf.Deserialize(file);
file.Close();
Debug.Log ("Loaded");
}
}
}
答案 0 :(得分:0)
调用Debug.Log(bf.Deserialize(file));
查看它返回的对象类型,因为它显然不是int。
答案 1 :(得分:0)
好的,所以当你问三个关于同一问题的问题时,让我们完成这件事。 我将向您展示该过程的简化版本,因为您有太多数据。
[Serializable]
public class DataContainer
{
public int dataA { get; private set; }
public int dataB { get; private set; }
public void SetValues(int a, int b){
this.dataA = a; this.dataB = b;
}
}
这是你的数据容器,没有静态值。成员是具有公共getter的属性,因此您可以从任何地方查看其值,但是setter是私有的,因此您必须使用该方法来修改它们。该方法可以有更多关于验证,例如,值是正值,还是小于屋顶值等等。
现在您需要实例化对象,以便可以访问数据。您可以在MonoBehaviour脚本中执行此操作:
public class DataController : MonoBehaviour
{
private DataContainer data = null; // here is the reference
void Start()
{
this.data = new DataContainer(); // Instantiate the object
this.data.SetValues(10,20);
Debug.Log(this.data.dataA + " " this.data.dataB);
}
}
好吧,到目前为止,这么好,让我们进行序列化和保存。
public static class Save
{
public static void SaveData<T>(object obj, string key) where T : class
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, items as T);
PlayerPrefs.SetString(key, Convert.ToBase64String(ms.GetBuffer()));
}
public static T GetData<T>(string key) where T: class
{
string str = PlayerPrefs.GetString(key, null);
if (string.IsNullOrEmpty(str) == true) { return null; }
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream(Convert.FromBase64String(str));
return bf.Deserialize(ms) as T;
}
}
这将存储在PlayerPrefs中,它使用泛型,因此您可以传递任何类型并重用任何项目的代码。有一个约束,所以你可以返回null。这意味着您只能传递类的类型并且不能传递struct。其余的已经知道了。只需关注转换(如T),这就是编译器理解预期类型的原因。
以下是您使用它的方式:
public class DataController : MonoBehaviour
{
private DataContainer data = null; // here is the reference
void Start()
{
this.data = new DataContainer(); // Instantiate the object
this.data.SetValues(10,20);
Debug.Log("Data : " + this.data.dataA + " " this.data.dataB);
Save.SaveData<DataContainer>(this.data, "data");
// At that point it is saved on disk
// Let's get it back
DataContainer newData = Save.GetData<DataContainer>("data");
Debug.Log("New data : " + newData .dataA + " " newData.dataB);
}
}