1
\$\begingroup\$

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 PlayerPrefsto 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.

UPDATE 1 (as of 5/22/2017) As requested by @DMGregory, 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.

            FileStream file = File.Create (Application.persistentDataPath + "/check/treeData2.dat");
            TreeData2 data2 = new TreeData2();

            . . .

            DataContractSerializer ds = new DataContractSerializer (data2.GetType ()); // --> Error stops here. Returns NullPointerException due to failed in parsing in .xml file in storing GameObject classes and List<T>.
            MemoryStream stream = new MemoryStream();

            ds.WriteObject (stream, data2);
            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);
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Can you show us what type you were using for data2 at the time of the error? \$\endgroup\$
    – DMGregory
    May 19, 2017 at 12:34
  • \$\begingroup\$ @DMGregory I updated the description of this post Check it out at the UPDATE 1 section. \$\endgroup\$ May 22, 2017 at 1:14
  • \$\begingroup\$ Content inside TreeData2 classes is revised. \$\endgroup\$ May 25, 2017 at 1:29

1 Answer 1

1
\$\begingroup\$

Unfortunately, after several experiments to find the easy way to store GameObjects effectively without hassle, there is no shortcut in preserving files + game objects during save and load state. I decided to give up for banging my head too hard to go crazy in making expectations on saving scene in one go. There are many steps to understand it.

Right now, storing info on each game object's specified sections/components require complex serializable classes, a meticulous way for sharing and retrieving each part of data. Explanation on this link and for more effective way in preserving data (but still not on game object) via formatting into JSON file.

It is a wise choice to make a better roadmap for tracking last state from scratch if you want to make your own save/load state for both common variables, serializable classes, and game object.

UPDATE:

However, there is another way to save and load GameObject using this solution found on this Unity Q&A section. It discusses about "SerializerHelper" that lets you serialize not only serialized classes but also game objects, scenes and other non-serializable classes. Check this forum as well in order to understand how it works. You can try this Unity package to try out saving/loading GO here to download. (Requires to register Dropbox account if needed.)

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .