- Home /
XML, Saving Data of Lists gives error
I'm trying to save character data for a game. I tried using xml but i get an error when instantiating the player, and i cant figure out why. In the players start method i try saving for testing. Would anyone like to take a look? It would be much appreciated. i listed below the error, followed by both scripts im using for the xml part of my game, the rest is not "involved" with these scripts.
InvalidOperationException: To be XML serializable, types which inherit from IEnumerable must have an implementation of Add(System.Object) at all levels of their inheritance hierarchy. UnityEngine.Transform does not implement Add(System.Object).
System.Xml.Serialization.TypeData.get_ListItemType ()
System.Xml.Serialization.TypeData.get_ListItemTypeData ()
System.Xml.Serialization.TypeData..ctor (System.Type type, System.String elementName, Boolean isPrimitive, System.Xml.Serialization.TypeData mappedType, System.Xml.Schema.XmlSchemaPatternFacet facet)
System.Xml.Serialization.TypeData..ctor (System.Type type, System.String elementName, Boolean isPrimitive)
System.Xml.Serialization.TypeTranslator.GetTypeData (System.Type runtimeType, System.String xmlDataType)
System.Xml.Serialization.TypeTranslator.GetTypeData (System.Type type)
System.Xml.Serialization.XmlReflectionImporter.GetReflectionMembers (System.Type type)
System.Xml.Serialization.XmlReflectionImporter.ImportClassMapping (System.Xml.Serialization.TypeData typeData, System.Xml.Serialization.XmlRootAttribute root, System.String defaultNamespace)
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping (System.Xml.Serialization.TypeData typeData, System.Xml.Serialization.XmlRootAttribute root, System.String defaultNamespace)
Rethrow as InvalidOperationException: There was an error reflecting type 'Player'.
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping (System.Xml.Serialization.TypeData typeData, System.Xml.Serialization.XmlRootAttribute root, System.String defaultNamespace)
System.Xml.Serialization.XmlReflectionImporter.ImportTypeMapping (System.Type type, System.Xml.Serialization.XmlRootAttribute root, System.String defaultNamespace)
System.Xml.Serialization.XmlSerializer..ctor (System.Type type, System.Xml.Serialization.XmlAttributeOverrides overrides, System.Type[] extraTypes, System.Xml.Serialization.XmlRootAttribute root, System.String defaultNamespace)
System.Xml.Serialization.XmlSerializer..ctor (System.Type type)
Player.Save () (at Assets/Scripts/Player.cs:46)
Player.Start () (at Assets/Scripts/Player.cs:30)
|===================================Player.CS======================================|
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
[XmlRoot("PlayerCollection")]
public class Player : MonoBehaviour {
[XmlArray("PlayerData")]
[XmlArrayItem("Players")]
public List<PlayerData> saveData;
public float timeDelay = 0.1f;
public string myPass = "arandompass";
public string isModded = "false";
public string myArea = "where i am";
public Vector3 myPos = Vector3.zero;
public string path = "";
void Start(){
if (saveData == null){
saveData = new List<PlayerData>();
}
saveData.Add(new PlayerData(myPass, isModded, myArea));
if(Network.isServer){
renderer.material.color = new Color(255, 0, 0);
}
if(!Network.isServer){
renderer.material.color = new Color(0, 0, 255);
}
Save();
}
void Update () {
if(networkView.isMine){
float vertDir = Input.GetAxis("Vertical") * 3 * Time.deltaTime;
float horDir = Input.GetAxis("Horizontal") * 3 * Time.deltaTime;
if(Input.GetAxis("Vertical") != 0){
transform.Translate(0, 0, vertDir);
}
if(Input.GetAxis("Horizontal") != 0){
transform.Translate(horDir, 0, 0);
}
}
}
void Save(){
var serializer = new XmlSerializer(typeof(Player));
var stream = new FileStream(path, FileMode.Create);
serializer.Serialize(stream, this);
stream.Close();
}
}
|===================================PlayerData.CS======================================|
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Xml;
using System.Xml.Serialization;
public class PlayerData{
[XmlAttribute("name")]
public string pass = "";
public string isMod = "";
public string area = "";
public PlayerData(string newpass, string newisMod, string newarea){
pass = newpass;
isMod = newisMod;
area = newarea;
}
}
Answer by zharramadar · Apr 08, 2014 at 05:38 PM
The problem is:
UnityEngine.Transform does not implement Add(System.Object)
Just saying out out my memory, cannot test this now, but or your Vector3 uses transform within it, or MonoBehavior is doing that. You cannot serialize anything that uses a transform class.
My suggestion would be to remove your player class from MonoBehavior, and create a class that inherits nothing, then use this class in another class that inherits MonoBehavior.
ok i tried what you said, (I think). Im having trouble with something though, how can i access the script that is not on any object? I wanted to make it a variable so i could do playerscript.DoStuff(); but that doesnt work. Im making an online game, so i think static scripts would be bad...im not certain though but i think static scripts are set for all online players on a server.
Something in this line: (some refactor from you may be required)
public class Player { [XmlArray("PlayerData")] [XmlArrayItem("Players")] public List saveData;
public float timeDelay = 0.1f;
public string myPass = "arandompass";
public string is$$anonymous$$odded = "false";
public string myArea = "where i am";
public Vector3 myPos = Vector3.zero;
}
public class PlayerProcessor : $$anonymous$$onoBehaviour {
public Player player = new Player();
public string path = "";
void Start(){
if (player.saveData == null){
player.saveData = new List<PlayerData>();
}
player.saveData.Add(new PlayerData(player.myPass, player.is$$anonymous$$odded, player.myArea));
if(Network.isServer){
renderer.material.color = new Color(255, 0, 0);
}
if(!Network.isServer){
renderer.material.color = new Color(0, 0, 255);
}
Save();
}
void Update () {
if(networkView.is$$anonymous$$ine){
float vertDir = Input.GetAxis("Vertical") * 3 * Time.deltaTime;
float horDir = Input.GetAxis("Horizontal") * 3 * Time.deltaTime;
if(Input.GetAxis("Vertical") != 0){
transform.Translate(0, 0, vertDir);
}
if(Input.GetAxis("Horizontal") != 0){
transform.Translate(horDir, 0, 0);
}
}
}
void Save(){
var serializer = new XmlSerializer(typeof(Player));
var stream = new FileStream(path, File$$anonymous$$ode.Create);
serializer.Serialize(stream, player);
stream.Close();
}
}
ok, im trying this, having an error with a default constructor,(`InvalidOperationException: PlayerData cannot be serialized because it does not have a default public constructor`) but when i figure that out ill post what ive got and let you know what is happening.
Your answer
Follow this Question
Related Questions
I dont understand why the script to read .xml doesnt works. 1 Answer
A node in a childnode? 1 Answer
Saving new children/subchildren in XML 0 Answers
Can I use IENumerable.Repeat in Unity? 0 Answers
Saving usermade creations in game 1 Answer