I humbly ask for help in order to solve this problem. I successfully take a quick guide to learn more about save and load state of the game. Basically first, I know how to use PlayerPrefs
to store basic string, int, and float.
Now, looking for a more effective way to store saved files via serialization. At first, after my first few researches online, I watch some video tutorial and only provides storing basic fields (int, string, bool, float, etc.) and saved in a created file. I attempt to try it on classes but didn't worked unless I marked as [Serializable]
.
Next, trying to save Gameobject created, prefabs or not, didn't work and it requires to serialize that class itself that is "GameObject". I took first attempt using this guide from StackOverflow with the accepted answer, I do understand and saving a GameObject or other custom classes require to store it and converted into .xml file.
Here's my two main problem need to resolve. the first one is that the runtime returned NullPointerException
after I ensured all of the necessary objects are created as new. The error stopped at this line (ask for more code source if you need):
DataContractSerializer ds = new DataContractSerializer (data2.GetType ()); // --> Serialize to .xml file.
MemoryStream stream = new MemoryStream();
ds.WriteObject (stream, data2); // --> The error stops here.
stream.Seek (0, SeekOrigin.Begin);
file.Write (stream.GetBuffer (), 0, stream.GetBuffer ().Length);
file.Close();
As you can see, this is the part of the code where you can save and stored in a file created on a persistent file directory for the stored classes such as GameObject, List, and/or other custom classes.
The second problem will be tackled after the first problem is resolved. The second problem involves loading last state saved. For the normal fields such as integer or string, using BinaryFormatter
and FileStream
works well to load stored values form a file created last time. I tried that on stored custom classes such as GameObject
but it required a different method like this one but it is a bit hard to understand how to translate it in Unity and still observe some ways to work it out, the best way to load stored classes from a file.
Here is the class I'm trying to deserialize a class that contains the following fields inside.
[DataContract]
public class TreeData2 {
// - - - Spouse - - -
[DataMember] private List<GameObject> _masters;
public List<GameObject> masters {
get { return _masters; }
set { _masters = value; }
}
[DataMember] private List<GameObject> _targets;
public List<GameObject> targets {
get { return _targets; }
set { _targets = value; }
}
[DataMember] private List<FamilyDatabase> _familyGroup;
public List<FamilyDatabase> familyGroup {
get { return _familyGroup; }
set { _familyGroup = value; }
}
[DataMember] private GameObject _node;
public GameObject node {
get { return _node; }
set { _node = value; }
}
[DataMember] private List<string> _mothers;
public List<string> mothers {
get { return _mothers; }
set { _mothers = value; }
}
[DataMember] private List<string> _fathers;
public List<string> fathers {
get { return _fathers; }
set { _fathers = value; }
}
[DataMember] private List<GenerationDatabase> _genDb;
public List<GenerationDatabase> genDb {
get { return _genDb; }
set { _genDb = value; }
}
// - - - Root Action - - -
[DataMember] private List<GameObject> _child;
public List<GameObject> child {
get { return _child; }
set { _child = value; }
}
// Gen Database (Main)
[DataMember] private List<string> _mothersDB;
public List<string> mothersDB {
get { return _mothersDB; }
set { _mothersDB = value; }
}
[DataMember] private List<string> _fathersDB;
public List<string> fathersDB {
get { return _fathersDB; }
set { _fathersDB = value; }
}
[DataMember] private List<GameObject> _mastersDB;
public List<GameObject> mastersDB {
get { return _mastersDB; }
set { _mastersDB = value; }
}
[DataMember] private List<GameObject> _targetsDB;
public List<GameObject> targetsDB {
get { return _targetsDB; }
set { _targetsDB = value; }
}
[DataMember] private List<string> _mothersT;
public List<string> mothersT {
get { return _mothersT; }
set { _mothersT = value; }
}
[DataMember] private List<string> _fathersT;
public List<string> fathersT {
get { return _fathersT; }
set { _fathersT = value; }
}
[DataMember] private List<GameObject> _mastersT;
public List<GameObject> mastersT {
get { return _mastersT; }
set { _mastersT = value; }
}
[DataMember] private List<GameObject> _targetsT;
public List<GameObject> targetsT {
get { return _targetsT; }
set { _targetsT = value; }
}
}
data2
is the variable name of the TreeData2
class and yes I'm making a family tree like structure via Unity for the game that shows progress of unlocking and storing lists of the branches. Here's the recap with the mentioned variable name while serializing GameObject and List classes.
FileStream file = File.Create (Application.persistentDataPath + "/check/treeData2.dat");
TreeData2 data2 = new TreeData2();
. . .
DataContractSerializer ds = new DataContractSerializer (data2.GetType ());
MemoryStream stream = new MemoryStream();
ds.WriteObject (stream, data2); // --> Error stops here. Returns NullPointerException due to failed in parsing in .xml file in storing GameObject classes and List<T>.
stream.Seek (0, SeekOrigin.Begin);
file.Write (stream.GetBuffer (), 0, stream.GetBuffer ().Length);
file.Close();
string result = XElement.Parse(Encoding.ASCII.GetString(stream.GetBuffer()).Replace("\0", "")).ToString();
print ("SAVE TREE COMPLETE");
print ("Result: " + result);
Redirect from this original question from Game Development.