0
\$\begingroup\$

I am pretty new to unity but I am not new to programming. I am building a Hololens application in Unity 2017.2 and it communicates with a REST api that I built. I am using Unity as a front end more or less and it manages my state. Coming from the web developement world, I have my server converting my models into JSON and I am sending that as a response. For the most part, it works well but since Unity works on an older version of C#, I am having issues working with the JSON data, mainly if the data type is not a string, int, float, or double. For example, if my model contains a date data type I am having issues converting it back into a c# model or even arrays are proving to be a pain. I don’t want to rely on unity packages too much as most I have tried don’t do what I need but I am open to any good ones if you know of any.

My question is, what is the best way to send data from my API to Unity? Should I send xml or a csv instead? Or even a more C# native approach? (If that makes sense)

\$\endgroup\$
  • 2
    \$\begingroup\$ There is never just one best way. Only the way which works best for your particular project. There is a myriad of different data exchange formats. Which one fits you depends on your data. \$\endgroup\$ – Philipp Dec 22 '17 at 8:16
  • \$\begingroup\$ I found a solid solution for me last night. I posted it below. \$\endgroup\$ – Christian4423 Dec 22 '17 at 15:43
1
\$\begingroup\$

I was able to find a solid solution at this link

I put the static method in my server

public static string GetXMLFromObject(object o)
{
    StringWriter sw = new StringWriter();
    XmlTextWriter tw = null;
    try
    {
        XmlSerializer serializer = new XmlSerializer(o.GetType());
        tw = new XmlTextWriter(sw);
        serializer.Serialize(tw, o);
    }
    catch (Exception ex)
    {
        //Handle Exception Code
    }
    finally
    {
        sw.Close();
        if (tw != null)
        {
            tw.Close();
        }
    }
    return sw.ToString();
}

And all worked well.

And then the method for sending the response called the function like in the link

[HttpGet]
public string GetData(){
    Employee emp = new Employee();
    emp.FirstName = "Code";
    emp.LastName = "Handbook";
    string xml = GetXMLFromObject(emp);
    return xml;
}

And in my Unity C# script, I parsed the response using the second static method given in the link but two changes had to be made.

public static Object ObjectToXML(string xml, Type objectType)
{
    StringReader strReader = null;
    XmlSerializer serializer = null;
    XmlTextReader xmlReader = null;
    Object obj = null;
    try
    {
        strReader = new StringReader(xml);
        serializer = new XmlSerializer(objectType);
        xmlReader = new XmlTextReader(strReader);
        obj = serializer.Deserialize(xmlReader);
    }
    catch (Exception exp)
    {
        //Handle Exception Code
    }
    finally
    {
        if (xmlReader != null)
        {
            xmlReader.Close();
        }
        if (strReader != null)
        {
            strReader.Close();
        }
    }
    return obj;
}

The changes were easy enough to implement, they were: Unity C# does not support XmlReader using the System namespace so I had to add a conditional statement to the using statement. You can read more about it in the official unity documentation here

#if NETFX_CORE
using XmlReader = WinRTLegacy.Xml.XmlReader;
#else
using XmlReader = System.Xml.XmlReader;
#endif

The second change was that strReader.Close() does not exist in the Unity C# scripting.

Change this:

if (strReader != null)
{
    strReader.Close();
}

To this:

if (strReader != null)
{
    strReader.Dispose();
}

I found that solution in a forum here

One last thing to note, Object was giving me some issues so I had to add the System to it. System.Object although Visual Studio said I did not need it, errors were thrown with out it. The final method looked like this:

public static System.Object ObjectToXML(string xml, Type objectType)
{
    StringReader strReader = null;
    XmlSerializer serializer = null;
    XmlTextReader xmlReader = null;
    System.Object obj = null;
    try
    {
        strReader = new StringReader(xml);
        serializer = new XmlSerializer(objectType);
        xmlReader = new XmlTextReader(strReader);
        obj = serializer.Deserialize(xmlReader);
    }
    catch (Exception exp)
    {
        //Handle Exception Code
    }
    finally
    {
        if (xmlReader != null)
        {
            xmlReader.Close();
        }
        if (strReader != null)
        {
            strReader.Dispose();
        }
    }
    return obj;
}

And to use it, I did this:

// handled response above
string xml = response.text;
Employee emp = new Employee();

try{
    System.Object obj = ObjectToXML(xml,typeof(Employee));
    emp = (Employee)obj;
}
catch (Exception ex){
    Debug.Log(ex.message);
    emp = null;
}
finally{
    if(emp != null){
        // do stuff
    }
    else{
        // handle error
    }
}

This was a lot easier than trying to parse JSON and I am able to throw the XML right into an object. The actual object I used was more complex than the Employee example and it worked just fine.

| improve this answer | |
\$\endgroup\$
0
\$\begingroup\$

I’ve found using simplejson as an easy way to handle json responses

https://wiki.unity3d.com/index.php/SimpleJSON

For the setup, you just need to place the simplejson file in a project folder. When handling responses, you can access the data like this:

jsonresponse["players"][2]["items"][5].Value;

for string values, and:

jsonresponse["players"][1]["life"].AsInt;

for int values and so on.

It solves the problem of having to predefine the expected json response data beforehand.

| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.