RTS Import XML

Hello guys,
I am quite new to Unity and Coding, and I have been googling for over 8hours to find a proper tutorial so i can learn how to do it myself. Unfortunately all tutorials are REALLY old and dont seem to work anymore.

What I try to achieve is having a XML file where I store data like this:

<building>
<id>0</id>
<name>House1</name>
<gold>100</gold>
<wood>200</wood>
</building>

Then Ingame I would like to have an Image when I hover them it shows the required Materials(in this case 100gold and 200wood) an if I do have the materials I can click it and place it.

The Issue I have is that I dont know how to get these Informations from XML over to Unity. Ive looked up XML-Serialization. Is this still the way? And If so…HOW do I achieve that? I would really appreciate your help and hints. Because I am going crazy ^^

It would be enough just to get the variable of the id over to unity as an example,I would do the rest on my own as I want to learn and not take premade code and have no clue what it is doing :slight_smile:

Thanks in advance!

I assume you know how to load/save xml, and that your main issue is to transform the xml string to/from actual object. I will provide sample with Id property only, as you requested :slight_smile:

But before I start - in case of xml serialization, it’s no difference if you do it in Unity or in any other C# application - all work exactly the same way. At least I haven’t encountered any differences yet…

First thing, is to create a class with properties that map on elements in your xml file. In case of your building, the simplest class would be:

public class building
{
    public int id { get; set; }
}

Sometimes it is necessary to decorate class and its properties with attributes, that inform serializer how to perform serialization and deserialization. For example, when I write C# classes, I always follow standard naming rules, so class name and property names always start with capital letter, so the class becomes:

public class Building
{
    public int Id { get; set; }
}

Serializing an instance of this class, would produce xml like:

<Building>
  <Id>1</Id>
</Building>

because serializer doesn’t know you want the xml attributes to be all lowercase. To fix this, you need attributes:

[XmlRoot("building")]
public class Building
{
    [XmlElement("id")]
    public int Id { get; set; }
}

If you want to use slightly more complicated xml, and serialize list of buildings, then you need two classes:

[XmlRoot("buildings")]
public class BuildingsCollection
{
    [XmlElement("building")]
    public List<Building> Buildings { get; set; }
}

public class Building
{
    [XmlElement("id")]
    public int Id { get; set; }
}

Please note, that when you serialize BuildingsCollection class, you no longer need XmlRoot attribute on Building class - attribute on BuildingCollection.Buildings property handles this case. If, however, you sometimes want to serialize BuildingsCollection, and sometimes Building, then you should add that attribute back.

Don’t forget about required namespaces: System.Collections.Generic, and for attributes: System.Xml.Serialization.

If you need to create more complex classes, you need to read a bit more about serialization. You can try some online tools as well, e.g. this xml to C# classes converter

After you created the class/classes, the only thing left is to actually serialize/deserialize. You can use simple helper:

using System.IO;
using System.Text;
using System.Xml.Serialization;

public class SerializationHelper
{
    public static string Serialize<T>(T data)
    {
        var sb = new StringBuilder();
        var serializer = new XmlSerializer(typeof(T));
        using (var writer = new StringWriter(sb))
        {
            serializer.Serialize(writer, data);
        }
        return sb.ToString();
    }

    public static T Deserialize<T>(string xml)
    {
        var serializer = new XmlSerializer(typeof(T));
        using (var reader = new StringReader(xml))
        {
            return (T)serializer.Deserialize(reader);
        }
    }
}

and then call it like:

var xml = SerializationHelper.Serialize(new Building { Id = 1 });
var buildingCollection = SerializationHelper.Deserialize<BuildingsCollection>(@"
<buildings>
    <building>
        <id>10</id>
    </building>
    <building>
        <id>20</id>
    </building>
</buildings>");

When you serialize the data, resulting xml will contain some additional data - xml declaration at the beginning, and attributes in the root element. That’s perfectly ok.