I am trying to implement save and load mechanic to my game. Hovewer for some reason it doesnt want to work. I keep getting the same error message : XmlException: The data at the root level is invalid. Line 1, position 1.
XmlException: The data at the root level is invalid. Line 1, position 1.
. Here's my code to create the serialized xml file:
public void Save()
{
Save newsave = new Save();
if (Time.timeScale == 0)
{
int unit_id = 0;
GameObject[] units = new GameObject[check_number_of_units()];
GameObject[] friendlies = GameObject.FindGameObjectsWithTag("Friend");
GameObject[] enemyosldiers = GameObject.FindGameObjectsWithTag("Enemy");
GameObject[] allunits = enemyosldiers.Concat(friendlies).ToArray();
foreach (GameObject g in allunits)
{
Debug.Log(unit_id);
Debug.Log(check_number_of_units());
units[unit_id] = g;
unit_id++;
}
newsave.cash = id.cash;
newsave.enemy_cash = id.enemycash;
newsave.units = units;
newsave.scenename = SceneManager.GetActiveScene().name;
FileStream file = File.Create(Application.persistentDataPath + "/gamesave.save");
DataContractSerializer bf = new DataContractSerializer(newsave.GetType());
MemoryStream streamer = new MemoryStream();
bf.WriteObject(streamer, newsave);
file.Write(streamer.GetBuffer(), 0, streamer.GetBuffer().Length);
file.Close();
}
}
Here's the Save class:
[System.Serializable]
[DataContract]
public class Save
{
[DataMember]
public int cash;
[DataMember]
public int enemy_cash;
[DataMember]
public string scenename;
[DataMember]
public GameObject[] units;
}
And here's the deserialization code:
public void Load()
{
if (File.Exists(Application.persistentDataPath + "/gamesave.save"))
{
Save loadedsave = new Save();
DataContractSerializer bf = new DataContractSerializer(loadedsave.GetType());
FileStream file = File.Open(Application.persistentDataPath + "/gamesave.save", FileMode.Open);
loadedsave = (Save)bf.ReadObject(file);
file.Close();
scene_has_been_loaded = true;
units = loadedsave.units;
cash = loadedsave.cash;
enemycash = loadedsave.enemy_cash;
SceneManager.LoadScene(loadedsave.scenename);
}
}
I'm lost. What makes all of this even more confusing is the fact that the error only appears when allunits[]
isn't empty
The problem is with this line:
file.Write(streamer.GetBuffer(), 0, streamer.GetBuffer().Length);
You generally don't want to access stream's data via GetBuffer()
, because it returns underlying byte array which can be larger than the data you wrote into the stream .
Either use stream.CopyTo
method like this:
streamer.Seek(0, SeekOrigin.Begin); // dont forget to seek to the start of the stream
streamer.CopyTo(file);
Or simply write directly to the file, without using MemoryStream
at all:
FileStream file = File.Create(Application.persistentDataPath + "/gamesave.save");
DataContractSerializer bf = new DataContractSerializer(newsave.GetType());
bf.WriteObject(file , newsave);
file.Close();
You colud try to create a model class for your units, thar store the properties, that are needed to reconstruct the GameObjects. I would not expect GameObject to be XmlSerializable since the XmlSerializer must know which System.Type to instanciate to fill the array. GameObject is a abstract class and therefore not instanciable.
[DataContract]
public class Unit
{
[DataMember]
public bool IsFriend { get; set; }
[DataMember]
public string Name { get; set; }
}
请检查您是否像为 Save 对象那样设置了GameObject 可序列化。
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.