In this section, we will create the C# script that will parse the XML data from the server to use in the next step. We will create the C# script because it is much easier to use the XmlDocument
from .Net
framework in C#.
Let's go to Assets | Create | C Sharp Script and name it XMLParser
and put it inside the Standard Assets
folder, as shown in the following screenshot:
Before we begin to code the C#, we should know that the way to write the script in C# is different from Unity JavaScript (we can see more details in Appendix C, Major Differences Between C# and Unity JavaScript), which we already know from the previous chapter. However, we will have a quick refresh of the idea for writing C#. First of all, when we declare the variable in C#, we will use Type varName = value;
instead of var varName : Type = value;
in Unityscript. Second, when we create the function in C#, the syntax is very similar to when we create the variable. We will use something like public void functionName () { ... }
instead of public function functionName () : void { ... }
that we used in Unityscript. Also, if we want the function to return the type, we will just replace the word void
with the type that we want. For example, if we want this function to return the string
type, we will write the code like public string functionName () { ... }
. It's just a small switch of the syntax. Also, if we take a look at the C# syntax, we will see that in C# we don't use the words function
or var
to declare either the variable or function. It only uses the type to declare.
We will double-click the XMLParser
script that we just created to open it in MonoDevelop:
XMLParser
script, as shown in the following highlighted code:using UnityEngine;
using System.Collections;
using System.Xml;
public static class XMLParser { private static XmlDocument doc; private static static XmlNode root; private string[] names; private static int[] scores; private static int userLength;
Parse()
function to parse the XML string. Let's type it as follows:public static void Parse( string xml) { doc = new XmlDocument(); doc.LoadXml(xml); // Loading from String //Using doc.Load("HiScore.xml"); When load from an xml file //Using Last Child to Skip the <?xml version="1.0" encoding="UTF-8"?> //If we load from the xml file we will use the FirstChild instead root = doc.LastChild; if (root.HasChildNodes) { //Getting the Node Length userLength = root.ChildNodes.Count; names = new string[userLength]; scores = new int[userLength]; for (int i = 0; i < userLength; i++) { //Getting the user name and score XmlAttribute XmlAttribute nameAtt = root.ChildNodes[i].Attributes["name"]; XmlAttribute scoreAtt = root.ChildNodes[i].Attributes["score"]; //Assigning the user name data to array names[i] = (string)nameAtt.Value; //Assigning the user score data to array scores[i] = ConvertStringtoInt((string)scoreAtt.Value); } } }
ConvertStringtoInt()
function, which will convert the string type to integer type as well as create the Name()
, Score()
, and UserLength()
functions as follows://Converting string to int private static int ConvertStringtoInt( string s) { int j; bool result = System.Int32.TryParse(s, out j); if (true == result) { return j; } else { Debug.Log("Error..."); return 0; } } //Getting user name from index public static string Name ( int index) { return names[index]; } //Getting user score from index public static int Score ( int index) { return scores[index]; } //Getting user length public static int UserLength () { return userLength; } }
In this section, we basically just created the C# XMLParser
script, to parse the XML string that we loaded from the server, and then we stored the user's data in this class to use it at a later stage.
First, we used the static
keyword for this class, because we want it to be accessible from the entire project. Then, we created the XmlDocument
and XmlNode
parameters to hold the XML data that we want to parse. Then, we have one array of string
and one array of int
to store the users' name and score. And the last parameter is to store the length of the users that we got from the XML data.
Next, we created the Parse(string xml)
function. This function will create the XmlDocument
and we use LoadXml(xml)
to load the string XML that we pass to this function. Then, we get the XmlNode
from the last child of the XmlDocument
:
root = doc.LastChild;
We used LastChild()
because we want to skip the first node, which is the headline of the XML file <?xml version="1.0" encoding="UTF-8"?>
. After we got the root
XmlNode
, we checked for the child in this node, assigned the number of its children, and created the array to store username and score data from this node:
//Getting the Node Length userLength = root.ChildNodes.Count; names = new string[userLength]; scores = new int[userLength]; Then, we loop to all the children, get the attribute of each child, and store it tonames[]
andscores[]
array by using the script below: for (int i = 0; i < userLength; i++) { //Getting the user name and score XmlAttribute XmlAttribute nameAtt = root.ChildNodes[i].Attributes["name"]; XmlAttribute scoreAtt = root.ChildNodes[i].Attributes["score"]; //Assigning the user name data to array names[i] = (string)nameAtt.Value; //Assigning the user score data to array scores[i] = ConvertStringtoInt((string)scoreAtt.Value); }
Since scoreAtt.Value
is a string and we want to store it as an integer, we need to convert the string data to an integer by creating the function that will convert the string
type to int
type, which we call ConvertStringtoInt( string s)
.
private int ConvertStringtoInt( string s) { int j; bool result = System.Int32.TryParse(s, out j); if (true == result) { return j; } else { Debug.Log("Error..."); return 0; } }
From the preceding function, first we create the int
variable j
, and then we use System.Int32.TryParse(s, out j);
to convert the string to an integer. This function will return the result true
or false
; if true
, it means that the result got converted to an integer, and then we return j
, which is the output from the System.Int32.TryParse(s, out j);
function. On the other hand, if the result is not an integer, we trace out the error and return 0
.
For example, if we created the C# script named Test
, as shown in the following script, and attach this script to the game object in Unity, we will see the trace result display i = 5
and j = 0
:
using UnityEngine; using System.Collections; public class Test : MonoBehaviour { // Use this for initialization public void Start() { int i; int j = Testout(out i); Debug.Log("i = " + i); //Will show the result i = 5 Debug.Log("j = " + j); //Will show the result j = 0 } public int Testout(out int i) { i = 5; return 0; } }
Then, the rest of the XMLParser
script is to get the value for the length of user, the username, and score. We create this function because we only want to get the data from this XML class, we don't need to set it. This is just some protection to make sure that our user's data that loaded from the XML doesn't change.
At the beginning of this section, we added the XMLParser
script to the Standard Assets
folder. Why did we do that? Is it really important to add the script in the Standard Assets
folder? The answer is "Yes". We need to put this script in the Standard Assets
folder. This is because of the way Unity builds the script. In Unity, the JavaScript is built first and then the C# script, so if we want to call a C# script from our JavaScript, we will get the error, as shown in the following screenshot (you can see more details in Appendix C, Major Differences between C# and Unity JavaScript):
So, the best way to do it is to code our entire project either in JavaScript or C#. However, there is a way to call the C# script function or class from Unity JavaScript, which is the way we just did in this chapter. As we know JavaScript is complied before the C# script. Also, all the code or scripts in the Standard Assets
folder will be compiled before the rest of the code in the project is compiled. So, we just reordered the code complier to compile XMLParser
first and then the rest of our code later.
We can read more details of the compiler order from the following Unity website:
http://unity3d.com/support/documentation/ScriptReference/index.Script_compilation_28Advanced29.html.
3.141.2.157