Tutorial: Loading and parsing external XML and JSON files with Unity

前端之家收集整理的这篇文章主要介绍了Tutorial: Loading and parsing external XML and JSON files with Unity前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

原文:http://blog.paultondeur.com/2010/03/23/tutorial-loading-and-parsing-external-xml-and-json-files-with-unity-part-1-xml/

Tutorial: Loading and parsing external XML and JSON files with Unity – Part 1: XML




As being a Flash Developer for many years,I’m very used to just quickly loading and parsing an external XML file. Although this is possible with Unity,I found out there’s very limited information about this subject available in a Unity context. While investigating this subject a while ago,I also decided to look into the JSON format as a data container,to see which works best for me. Naturally I’d prefer to use XML over JSON,but it turns out that both comes with their cons and pros,which makes it hard to say which works best.
In this two part tutorial I’ll show how you could load an XML or JSON file into Unity and parse it’s information. Both the XML file and JSON file are containers for the same information,which makes it easier to compare the differences between the two.

XML
The XML file I’ve created contains a couple of books. In order to cover different ways to work with XML,it contains a variety of data,like attributes,regular nodes and childnodes,integers,strings and CDATA blocks.

1
2
3
4
5
6
7
8
@H_404_48@ 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<? xml version = "1.0" ?>
< books >
book id "1" >
title >Papervision3D Essentials</ >
authors >
author >Paul Tondeur</ author >
"2" >Jeff Winder</ >
</ >
description >
<![CDATA[<p>Create interactive <b>Papervision3D</b> applications with stunning effects and powerful animations</p>]]>
>
book >
>
>Unity Game Development Essentials</ >
>
"3" >Will Goldstone</ >
>
>
<![CDATA[<p>Build fully functional,professional 3D games with realistic environments,sound,<i>dynamic effects</i>,and more!</p>]]>
>
>
>

This file can also be found on:http://paultondeur.com/files/2010/UnityExternalJSONXML/books.xmland will be loaded later on in this tutorial.

XML is not new to C#. In fact,it’s quite integrated within the language. When you create a new application in Visual Studio,you have access to theSystem.Xmlnamespace by default. Within this namespace,lots of classes can be found for creating,reading and modifying XML documents. Accessing these classes in Unity however,doesn’t work out of the Box. This is because this namespace isn’t available within Unity. The solution for this is relatively simple; We just need to reference the System.Xml dll in Unity. As Unity is build upon theMono Framework,this file is provided with your local Unity install. You can find these files at the following locations,depending on the machine you’re running on:

  • MAC: Go to /Applications/Unity/ and right-click on Unity.app -> Show Package Contents. Then browse to “Contents/Frameworks/Mono.framework/”. In this folder you’ll find lot’s of dll files. In this case,just copy System.Xml.dll
  • Windows: Go to C:\Program Files\Unity\Editor\Data\Frameworks\Mono.framework and copy System.Xml.dll from here.

The next thing to do is paste the dll into your assets folder of a Unity project. Next time you compile this project,the System.Xml namespace is available to you from within the Unity player.

To load any external content from a webserver with Unity,we can use the WWW class. (can be compared to a URLRequest in Flash).

Once the data is loaded we can instantiate a new XML document and load the XML by the data that has returned from the www class request.

2
XmlDocument xmlDoc = XmlDocument();
xmlDoc.LoadXml(www.data);

Instead of using E4X (as in Flash) to select childnodes inside the XML document,we have to make use of anXPath expression. In our case we want to select all books,which are nested inside the books element. Selecting nodes returns an XmlNodeList,which will be used to loop through all results. Take a look at how to select all book nodes and loop through them:

4
foreach (XmlNode node in xmlDoc.SelectNodes( "books/book" ) )
{
.....
}

Inside the loop we have access to the value “node“,which contains information of the selected book. Let’s say we want to access the title node value of the book and show it on the screen:

Debug.Log(node.SelectSingleNode("title").InnerText);

Accessing the description (which contains a CDATA block) is no different from selecting the title node:

"description").InnerText);

Selecting an attribute of a node works of course a bit different. When we want to access the book id attribute we do this as follows:

Debug.Log(node.Attributes.GetNamedItem("id").Value);

All values in an XML are of a String type by default. In this case the id attribute is clearly of an integer type. Although it wouldn’t make any sense in this case,casting it to an int can be achieved by using the Convert utils class:

Debug.Log(Convert.ToInt16(node.Attributes.GetNamedItem().Value));

Inside a book node,we can find an authors node,which contains nested author nodes inside. In order to loop through these,we can again use an XPath expression,only this time on the current selected node.

(XmlNode author node.SelectNodes("authors/author"))
Debug.Log(author.InnerText);
}

Around this concept of loading and parsing an XML file I’ve created a very small Unity application,which shows the two book covers on screen and calls a Debug.Log() on the author name on click on the book. The complete code can be found in the download at the bottom of this article. But the class that handles loading and parsing the XML looks as follows:

24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@H_681_502@ 57
58
59
60
61
62
63
64
65
66
using UnityEngine;
System.Collections;
System.Xml;
System;
public class LoadXML : MonoBehavIoUr
{
IEnumerator Start()
{
//Load XML data from a URL
string url = ;
WWW(url);
//Load the data and yield (wait) till it's ready before we continue executing the rest of this method.
yield return www;
if (www.error == null )
{
//Sucessfully loaded the XML
Debug.Log( "Loaded following XML " + www.data);
//Create a new XML document out of the loaded data
XmlDocument();
xmlDoc.LoadXml(www.data);
//Point to the book nodes and process them
ProcessBooks(xmlDoc.SelectNodes( ));
}
else
{
"ERROR: " + www.error);
}
}
//Converts an XmlNodeList into Book objects and shows a book out of it on the screen
private void ProcessBooks(XmlNodeList nodes)
{
Book book;
nodes)
{
book = Book();
book.id = Convert.ToInt16(node.Attributes.GetNamedItem( ).Value);
book.title = node.SelectSingleNode( ).InnerText;
book.image = node.SelectSingleNode( "image" ).InnerText;
book.description = node.SelectSingleNode( ).InnerText;
book.authors = ArrayList();
//Loop the authors
))
{
book.authors.Add(author.InnerText);
}
LoadBook(book);
}
}
//Finds book object in application and send the Book as parameter.
//Currently only works with two books
LoadBook(Book book)
{
GameObject bookGameObject = GameObject.Find( "Book" + book.id.ToString());
bookGameObject.SendMessage( "LoadBook" ,book);
}
}

With this example you should be able to load and parse your own XML files. Before doing this,I need to point you to the fact that using the System.Xml dll results in quite a large footprint to your application. In my tests it turned out that it was about an 850kb difference between having an empty Unity application and an application that is using the System.Xml dll.

In the next part of this tutorial I’ll demonstrate how you could achieve the same results with a JSON file as data container.







Tutorial: Loading and parsing external XML and JSON files with Unity – Part 2: JSON

原文:http://blog.paultondeur.com/2010/03/23/tutorial-loading-and-parsing-external-xml-and-json-files-with-unity-part-2-json/






In this part of the tutorial we’ll have a look at how to load the some book information in the JSON format into Unity. For good comparison between JSON and XML,this file will describe the same books and uses roughly the same structure. Take a look at how that looks:

29
{
"book":[
{
"id":"1",
"title":"Papervision3D Essentials",
"image":"http:\/\/paultondeur.com\/files\/2010\/UnityExternalJSONXML\/Papervision3DEssentials.jpg",
"authors":
{
"author":[
{"id":"1","name":"Paul Tondeur"},
{"id":"2","name":"Jeff Winder"}
]
},
"description":"<p>Create interactive <b>Papervision3D<\/b> applications with stunning effects and powerful animations<\/p>"
{
"id":"2",
"title":"Unity Game Development Essentials",
"image":"http:\/\/paultondeur.com\/files\/2010\/UnityExternalJSONXML\/UnityGameDevelopmentEssentials.jpg",
"authors":
{
"author":[
{"id":"3","name":"Will Goldstone"}
]
"description":"<p>Build fully functional,<i>dynamic effects<\/i>,and more!<\/p>"
]
}

This file can also be found onhttp://paultondeur.com/files/2010/UnityExternalJSONXML/books.jsonand will be used later on in this tutorial.

JSON isn’t as integrated in C# development as XML is. Furtunatly theJSON documentation websitelists external libraries that are available for a variety of languages. Including a couple C# projects. After having a glance at all,I found out that I likedLitJSONthe most. It’s usage is quite straight forward. The source of this project can be found on found on SVN. After checking this project out from SVN,you’ll end up with a couple of classes and make files. From these files,a dll should be created for use in Unity. This might sound a bit frightening when you’re new to C Sharp development. ThereforeI’ve already created this dllfor you (also included in the download at the end of this article). You just need to copy this into the asset folder of your Unity project and from then on you’ll have access to all classes inside of this dll. In order to use them in your scripts,you need to set the using directive on top of your class to:

UnityEngine;

Just like with XML,we can load the JSON file by using the WWW class.

Once the data is loaded from the provided URL,we need to convert the loaded string into an object of the JsonData type. We can use a static method of the JsonMapper class to achieve this:

JsonData jsonBooks = JsonMapper.ToObject(jsonString);

Now we have the string converted into an object,we can easily access the objects that have been defined in the JSON file. So let’s say we want access the book object and show how many books are nested:

Debug.Log(jsonBooks["book"].Count);

That looks easy,right? jsonBooks["book"] holds an array of books,so in order to loop through all books,we can use a simple for loop:

for(inti = 0; i<jsonBooks[].Count; i++)
......
}

In this example,it will loop through the two books. While looping through them,we can print the book title on the screen:

][i][].ToString());

Notice the ToString() method call at the end of the selected object. This will convert the object into a string. C# is more strict with this as compared to ActionScript,so never forget to call this to prevent errors.

Now let’s say you want to access the book ID and treat it as in integer. You first need to convert the object to a string and then convert it to an integer.

Debug.Log(Convert.ToInt16(jsonBooks[].ToString()));

Nested inside an book object are the authors. Looping through them is quite easy,as we can you access these nested elements. Look at how to loop through the authors and print their names on the screen:

j = 0; j<jsonBooks["authors"]["author"].Count; j++)
][j][ "name" ].ToString());
}

I’ve recreated the same example as used in part 1 of this tutorial,only this time with a JSON file as the data source. The complete source can be found in the download,however have a look at the following code to see how LitJSON could be used in production:

63
UnityEngine;
LitJson;
System;
System.Collections;
class LoadJSON : MonoBehavIoUr
//Load JSON data from a URL
url = WWW(url);
return www;
(www.error == //Sucessfully loaded the JSON string
"Loaded following JSON string" //Process books found in JSON file
ProcessBooks(www.data);
}
else
{
+ www.error);
}
//Converts a JSON string into Book objects and shows a book out of it on the screen
void ProcessBooks( jsonString)
{
JsonData jsonBooks = JsonMapper.ToObject(jsonString);
Book book;
].Count; i++)
{
Book();
book.id = Convert.ToInt16(jsonBooks[ ].ToString());
book.title = jsonBooks[ ].ToString();
book.image = jsonBooks[ ].ToString();
book.description = jsonBooks[ ].ToString();
ArrayList();
].Count; j++)
{
book.authors.Add(jsonBooks[ ].ToString());
}
LoadBook(book);
}
//Finds book object in application and send the Book as parameter.
//Currently only works with two books
LoadBook(Book book)
{
+ book.id.ToString());
}
}

This gives an idea how to handle JSON files in Unity. Just like with XML this comes with a disadvantage in terms of filesize. It’s size footprint to the Unity file is about equal to XML: +/- 850kb.A live example of this can be viewed here.

Conclusion
I think it’s quite hard to say which file format is better. Both XML and JSON add about the same amount of kilobytes to the Unity file. I’ve not tested which of these is more efficient performance wise. It might be worth checking that out before you’ll be working with large amounts of data. In case that doesn’t matter,I think it’s just a matter of personal taste. I think I kind of prefer to use JSON,as this reminds me of handling XML files with ActionScript in the AS2 days.
But give it a try yourself and see what works best for you.

Downloads / Examples

猜你在找的XML相关文章