City

Check out the class I have already set up for in in “Playfield.cs” called City

public class Playfield : MonoBehaviour
{
...
    /// <summary>
    /// This is the data structure we will be saving and loading
    /// City holds the entire city as a list of Element
    /// </summary>
    public class City
    {
        /// <summary>
        /// An Element is one object (like a building) in the City
        /// </summary>
        public class Element
        {
            public string m_type;
            public int m_x;
            public int m_z;
            public float m_rot;
        }
        public List<Element> m_elements;
    }
...
    // TODO add public function void SaveCity()
    // Save the city configuration to "City.xml"

    // TODO add public function void LoadCity()
    // Load the city configuration to "City.xml"
    // And instantiate all the objects in that file
}

By declaring a public class like this, C# will be able to serialize that in and out as an XML file using the standard XML serialization library.

  • TODO add public function void SaveCity()
  • Create a new local instance of a City
  • Go through all the objects in m_objects
    • Make a matching City.Element for each element of m_objects
    • The Key for m_objects is the GameObject
      • m_type is for the name of the object
        • The name of the object is going to have (clone) on the end of it
        • strip the (clone) off the name that you store in m_type
          (Perhaps use String.Substring)
      • m_rot is for storing the Y-rotation of the object
        (Available as transform.localEulerAngles.y)
    • The Value for m_objects is a Vector2Int of where that object is in the grid
      • m_x and m_z should store that information
    • Add all these City.Elements to m_elements
  • Create a StreamWriter to save the file
    • Put the file at Application.persistentDataPath + "/City.xml"
  • Create an XmlSerializer of type City
  • Serialize() your City to your StreamWriter using the XmlSerializer

User-saved data should be put into the folder Application.persistentDataPath.
Different platforms have different rules for where these files go.
Using that accessor ensures that the files are stored in the correct place on any platform.

Saving files to the wrong folder is likely to work in editor and fail on mobile platforms.
Never attempt to save files into local folders unless you are making an editor tool.

Load

  • TODO add public function void LoadCity()
  • First clear out any objects in the Playfield with a call to ClearObjects()
  • Create a new StreamReader
    • Open the file at Application.persistentDataPath + "/City.xml"
  • Read the file into a string
  • Create a StringReader from that string
  • Create an XmlSerializer of type City
  • Deserialize() the StringReader using your XmlSerializer
    • This should create a new local variable of type City
  • Instantiate all the objects in the City
    • m_prototypes is the parent of all the Prototype objects
    • Search through the children of m_prototypes to find one with a name matching m_type
    • If a match is found, call Prototype.MakeOne() to instantiate one
    • Use MoveObject() to place the new object into the Playfield in the correct location
      • Make a Vector2Int out of m_x and m_z
    • Set the Y-axis rotation accoring to m_rot

You should be able to save your scenes and load them.
Make sure loading a scene erases the old one.

Let’s commit and push.