孙广东  2015.6.25

Unity and JSON – Quick Guide:

相比較XML的沉重和密集,Json更加高效。

Introduction:

什么是 Json ?
假设你从未使用过它。它的内部是字典结构。但你进行序列化和反序列化一些数据之后,你就会想知道他是怎么工作的。

Unity没有为 JSON 提供内置的解决方式。

获得Dark Table的 JsonFX:

Dark Table 已经创建了Unity中的解决方式, JsonFx.  你能得到 DLL 在这, if you want to follow along.

下载它。而且拖拽到Unity项目中。放到Plugins文件里。

Our Data Classes:
来自 JsonFx zip 文件里的readme 自述文件。里面有支持的数据类型的列表。

我们会把它当作简单一些基元和数组 — — 仅仅是为了演示功能。

我已经创建了几个用于此演示样例中的类。我们有一个叫做的 DataPC的类,这是我们要为我们的Player Controller存储的信息。

还有提到的类名是 DataName 序列化的类。

我把这些作为数据类。由于他们的目的是要我的 JSON 文件,不是实际的类。

换句话说,我或许会有一个类调用 PC 来处理游戏中的功能,可是我简单的 DataPC 类能够帮助存储和检索 json 格式的数据。这不须要通过不论什么手段。

我创建的第二类是 DataItem 类。存储特定item的数据。

public class DataPC
{
public string name;
public int maxLevel;
public string description;
public string portrait; public DataItem[] inventory;
} public class DataItem
{
public string name;
public int cost;
}

在这里我们变得有点花哨: 我创建了一个 DataItem 数组来存储多个items。

Serializing the Data:
接下来。我已经成立了一个类,处理序列化和反序列化。:

using UnityEngine;
using System.Collections;
using JsonFx.Json; public class DataHandlerTest : MonoBehaviour
{
public DataPC myPC;
void Start()
{
myPC = new DataPC();
myPC.name = "Jimbob";
myPC.maxLevel = 99;
myPC.description = "Jimbob likes beer and trucks.";
myPC.portrait = "jimbob.png";
myPC.inventory = new DataItem[2]; myPC.inventory[0] = new DataItem();
myPC.inventory[1] = new DataItem(); myPC.inventory[0].name = "Silver Bullet";
myPC.inventory[0].cost = 5; myPC.inventory[1].name = "Shotgun";
myPC.inventory[1].cost = 200;
} public void OnGUI()
{
if (GUILayout.Button("SERIALIZE"))
{
string myJson = JsonWriter.Serialize(myPC);
Debug.Log(myJson);
}
}
}

首先要注意的是我们须要包含 JsonFx 库: using JsonFx.Json
接下来。我们创建的 DataPC 的一个新实例并初始化其值。

我们给它两个Items存入数组,初始化每一个。

在 OnGUI() 方法中。

string myJson = JsonWriter.Serialize(myPC);
Debug.Log(myJson);

我们这里在做什么? 将类序列化为 Json 并成一个字符串保存该 Json。一旦我们有字符串,我们打印出来到debug log。

此方法的一个小问题是它生成 JSON 是一行的,没有排版结构的换行等。无格式。这意味着有大量的数据时它是有点难读的,但你能够把这个Copy到您选择的文本编辑器。你也能够使用一个基于 web 的工具来做这样的。

这将格式设置为、并验证 Json。

{
"name":"Jimbob",
"maxLevel":99,
"description":"Jimbob likes beer and trucks.",
"portrait":"jimbob.png",
"inventory":[
{
"name":"Silver Bullet",
"cost":5
},
{
"name":"Shotgun",
"cost":200
}
]
}

JSON De/Serialization Using Unity and JsonFx:

目的:
        序列化数据的目的是使它能够存储或在不同的系统或甚至应用程序之间共享。

它创建一个共同的数据模板。能够来回转换 (序列化和反序列化) 甚至当源数据是不被觉得是由接收的系统或应用程序本身。有能够使用的各种常见格式 (即 XML。CSV,二进制文件里,或在我们的样例,JSON)、 序列化到数据。

在我们的演示样例中。我们要创建一个类,在我们的应用程序中;  当我们创建它的实例时。它将存在于内存中直到我们摧毁它或停止应用程序。

一旦我们在 unity 编辑器 (或关闭我们build生成中的窗体)关闭播放play模式。该数据就丢失了。通过序列化,在这样的情况下内容到一个文本文件。使用 JSON,我们能够将其存储到文件系统中。不仅我们能够脱机编辑和查看更改反映在我们的应用程序,当我们再次载入它。

Download the JsonFx DLL: here

步骤 1: 创建容器
容器是一个类用来在内存中存储您正在使用的数据。

这不是唯一的方式做到这一点,但由于你读了我的向导,我的容器直接使用 C# 类。我们有:

Sandwich.cs

using System.Collections;
using System.Collections.Generic; [System.Serializable]
public class Sandwich{
public string name;
public string bread;
public float price;
public List<string> ingredients = new List<string>();
}

仅仅是注意字段都是public的,这一点非常重要!  此外。[System.Serializable] 能为我们做两件事: 它同意 JsonFx 要序列化的字段,而且它还暴露在UNity的inspector面板上,将这些字段。
非常easy,对吧?好吧,让我们继续前进。

第 2 步: 序列化 (Saving/Writing) 数据
将从代码中入手,然后我将解释。
JsonTutorial.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Pathfinding.Serialization.JsonFx;
using System.IO; public class JsonTutorial : MonoBehaviour { public string fileName;
public Sandwich sandwich; private string PATH; private void Start() {
PATH = Application.dataPath + "/../testData/";
}
private void OnGUI() {
if (GUILayout.Button("SAVE")){
SerializeAndSave();
}
} private void SerializeAndSave() {
string data = JsonWriter.Serialize(sandwich);
if(!Directory.Exists(PATH)){
Directory.CreateDirectory(PATH);
}
var streamWriter = new StreamWriter(PATH + fileName + ".txt");
streamWriter.Write(data);
streamWriter.Close();
}
}

第一件事情就是包含 JsonFx dll 就像这样:

using Pathfinding.Serialization.JsonFx;

当然了详细的命名空间要依据DLL而定。假设你能够找到还有一个版本号的 dll,您将通过适当的命名空间 (即 JsonFx.Json)。
第二,我们包含 System.IO。

这是由于我们会读取和写入文件。

我会简单地填写字段通过Inspectors。以便您稍后能够看到的输出。

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDAxOTcxNw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center" />

没有必要给它扩展,由于你会注意到在 SerializeAndSave() 方法。我们给它一个自己主动化 (尽管你能够随时改动代码。以做到)。

接下来的几个字段也仅仅是我们早些时候在容器中定义。
string data = JsonWriter.Serialize(sandwich);

那一行,就在那里处理序列化到一个文件里对sandwich对象。JsonFx 为我们处理繁重的工作。你能够 Debug.Log(data),看看它的样子,但我们要把它写到一个文件里不管怎样,所以让我们继续。

下几行简单的核对是否我们指定的文件夹PATH路径存在。而且假设不存在就创建它。

请注意,默认情况下,Application.dataPath 是项目的 /Assets 文件夹。

我已经写到它下了,所以我仅仅是去一个文件夹 (......),并将保存到一个文件夹中我 MyProject/ (这样, /Assets。基本上)。

StreamWriter 构造函数实际上採用的全路径,包含文件名称。

再次,你能够简单地省去手动加入".txt"扩展名,并让用户填写文件名称变量,但随便。你将能够在文本编辑器中打开该文件,即使你没有给它的扩展。

測试它!
仅仅是作为一个组件在不论什么场景中,拖拽 JsonTutorial 脚本,你会看到一个“SAVE”button (记住 OnGUI )。

单击button。并检查您的project 文件夹。

能看到/testData 路径,不管名字是什么在 Inspectors 中 (在我的样例 my_data.txt) 中设置的文件。您应该看到一个 /testData 文件夹中。

基于我设计的sandwich。该文件将包含下面 JSON 作为文本 :

{ 

   "name": "meatball", 

   "bread": "white", 

   "price": 5.99, 

   "ingredients": [ 

      "metaballs", 

      "sauce", 

      "cheese" 

   ] 

}

我们能够甚至交换的东西有点通过提供它的 sandwiches 而不是仅仅是一个列表。

让我们创建一个简单的容器来存放列表sandwiches(这项工作,由于你无法反序列化List<Sandwiches> 直接要求。

In Sandwich.cs

[System.Serializable]
public class Sandwiches{
public List<Sandwich> sandwiches = new List<Sandwich>();
}

相反。你 Sandwich 变量,创建一个新的Sandwich 依次包含List<Sandwich> 依据我们的容器。

仅仅是别忘了更改 JsonWriter.Serialize(sandwich);到 JsonWriter.Serialize(sandwiches);在inspector中,加入一些 sandwiches 执行它。并查看你得到什么。

Step 3: Loading and Deserializing
做最难的部分,我们已经有我们须要的一切。所以剩下的就是创建一个方法来载入数据和一个button来调用该方法。

这里是我们的方法:
In JsonTutorial.cs

private void LoadAndDeserialize(){
var streamReader = new StreamReader(PATH + fileName + ".txt");
string data = streamReader.ReadToEnd();
streamReader.Close(); sandwiches = JsonReader.Deserialize<Sandwiches>(data);
}

它看起来相似于我们的 SerializeAndSave() 方法,可是我们通过阅读做在这儿的对面 (废话)。
与 StreamWriter相反。我们正在使用 StreamReader

与JsonWriter.Serialize相反,我们使用的 JsonReader.Deserialize。你会注意到的语法是有点不同,在这里。由于我们的读者须要知道什么类型要反序列化 (在本例中,Sandwiches )。和你通过它要反序列化。它是字符串的数据我们从回来我们 StreamReader。

步骤 4: 測试它......再一次!

终于代码
JsonTutorial.cs

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Pathfinding.Serialization.JsonFx;
using System.IO; public class JsonTutorial : MonoBehaviour { public string fileName;
public Sandwiches sandwiches = new Sandwiches();
//public List<Sandwich> sandwiches = new List<Sandwich>(); private string PATH; private void Start() {
PATH = Application.dataPath + "/../testData/";
}
private void OnGUI() {
if (GUILayout.Button("SAVE")){
SerializeAndSave();
}
if (GUILayout.Button("LOAD")){
LoadAndDeserialize();
}
} private void SerializeAndSave() {
string data = JsonWriter.Serialize(sandwiches);
if(!Directory.Exists(PATH)){
Directory.CreateDirectory(PATH);
}
var streamWriter = new StreamWriter(PATH + fileName + ".txt");
streamWriter.Write(data);
streamWriter.Close();
} private void LoadAndDeserialize(){
var streamReader = new StreamReader(PATH + fileName + ".txt");
string data = streamReader.ReadToEnd();
streamReader.Close(); sandwiches = JsonReader.Deserialize<Sandwiches>(data);
}
}

Sandwich.cs

using System.Collections;
using System.Collections.Generic; [System.Serializable]
public class Sandwich{
public string name;
public string bread;
public float price;
public List<string> ingredients = new List<string>(); public Sandwich() { }
} [System.Serializable]
public class Sandwiches{
public List<Sandwich> sandwiches = new List<Sandwich>();
}

学习JsonFX 的地方: http://www.raybarrera.com/2014/05/18/json-deserialization-using-unity-and-jsonfx/
http://www.raybarrera.com/2012/11/03/unity-and-json-quick-guide/
https://bitbucket.org/TowerOfBricks/jsonfx-for-unity3d/overview




Unity使用JsonFX插件进行序列化的更多相关文章

  1. Unity JsonFx 插件使用

    在Unity中使用 JsonFx 插件笔记(提示:以下在 Unity3D v5.4.0 版本 Win 平台下测试成功) 下载 JsonFx 插件注意:JsonFx 插件其实就是一个 dll 文件(如果 ...

  2. 玩转Unity资源,对象和序列化(下)

    本文将从Unity编辑器和运行时两个角度出发,主要探讨以下两方面内容:Unity序列化系统内部细节以及Unity如何维护不同对象之间的强引用.另外还会讨论对象与资源的技术实现差别. 译注:除非特别说明 ...

  3. 玩转Unity资源,对象和序列化(上)

    这是一系列文章中的第二章,覆盖了Unity5的Assets,Resources和资源管理 本文将从Unity编辑器和运行时两个角度出发,主要探讨以下两方面内容:Unity序列化系统内部细节以及Unit ...

  4. Unity时钟定时器插件

    Unity时钟定时器插件 http://dsqiu.iteye.com/blog/2020603https://github.com/joserocha3/KillerCircles/blob/67a ...

  5. Unity的NGUI插件篇——入场效果

    Unity的NGUI插件篇--入场效果 入场效果 入场效果须要借助于NGUI提供的TweenPosition类来完毕.为了说明此类的用法.本节将使会解说两个演示样例.本文选自  大学霸 <NGU ...

  6. 记录一个Unity播放器插件的开发

    背景 公司最近在做VR直播平台,VR开发我们用到了Unity,而在Unity中播放视频就需要一款视频插件,我们调研了几个视频插件,记录两个,如下: Unity视频插件调研 网上搜了搜,最流行的有以下两 ...

  7. Curved UI - VR Ready Solution To Bend Warp Your Canvas 1.7,1.8,2.2,2.3 四种版本压缩包(Unity UGUI曲面插件),可以兼容VRTK

    Curved UI - VR Ready Solution To Bend Warp Your Canvas 1.7,1.8,2.2,2.3 四种版本压缩包(Unity UGUI曲面插件) 可以兼容V ...

  8. Unity时钟定时器插件——Vision Timer源码分析之二

      Unity时钟定时器插件——Vision Timer源码分析之二 By D.S.Qiu 尊重他人的劳动,支持原创,转载请注明出处:http.dsqiu.iteye.com 前面的已经介绍了vp_T ...

  9. Unity使用protobuf-net进行二进制序列化与反序列化

    Protobuf-net提供的一种易于使用的数据序列化方案,可序列化带有[ProtoContract]特性的类实例,并可支持Unity各个发布平台,且效率高.易用性强. public static c ...

随机推荐

  1. Oracle学习笔记之七(用户管理、角色与权限、导入导出等)

    下面这些基本的SQL语句应该熟悉,能够灵活运用.最好在不查资料的情况下,能够写出如下的任何代码. 1. 用户操作 --create user username identified by passwo ...

  2. 鼠标经过显示二级菜单的js特效

    本文章来给大家推荐一个不错的鼠标经过显示二级菜单js特效效果,有需要了解的朋友可以参考一下 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 T ...

  3. js动态创建表格,删除行列的小例子

    js动态创建表格,删除行列的实例代码. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" &quo ...

  4. 【Android】7.1 布局控件常用的公共属性

    分类:C#.Android.VS2015: 创建日期:2016-02-10 一.简介 Android应用程序中的布局控件都是容器控件,用于控制子元素的排列和放置方式.Android提供的布局控件有: ...

  5. Test for Required Behavior, Not Incidental Behavior

    Test for Required Behavior, Not Incidental Behavior Kevlin Henney A COMMON PITFALL IN TESTING is to ...

  6. Python标准库:内置函数getattr(object, name[, default])

    本函数实现获取对象object的属性.属性由name来表示,就是属性名称的字符串.參数default是可选的參数,当获取对象的属性不存在时,就返回此值.假设没有提供此參数.同一时候在对象属性里也找不到 ...

  7. 解决NSImage绘制的时候图像模糊

    Mac下NSImage绘制模糊的原因之一是draw到了非整数像素上,框架在渲染的时候就会模糊. 针对这一原因写了以下工具: /** * @brief 一劳永逸的解决NSImage绘制的时候绘到浮点值像 ...

  8. IOC疑惑

    转载自:http://www.tuicool.com/articles/QfeEFn 大家好. 今天我来给大家扯扯IoC,以及StructureMap的一些简单应用(基本用法.自动装配.生命周期.延迟 ...

  9. mysql 5.7.14 安装配置方法图文教程(转)

    http://www.jb51.net/article/90259.htm ******************************** 因笔者个人需要需要在本机安装Mysql,先将安装过程记录如 ...

  10. POJ1579:Function Run Fun

    Description We all love recursion! Don't we? Consider a three-parameter recursive function w(a, b, c ...