如果您是一名程序员,则可能知道或听说过JSON数据的格式。但是,由于在很多情况下都使用了它,所以将库用于不同的语言和环境往往是一个好主意。此外,某些库还存在诸如不支持功能之类的陷阱。因此,这次,我将解释如何处理由Unity正式支持的Json Utility,注意事项和补救措施。
什么是JSON
施工
JSON:Javascript对象表示法的缩写,实际上是基于javascript数据结构。
JSON将键和值作为一个集合保存,但是由于您可以在该值中嵌套一个数组或一个互锁数组,因此可以在结构上拥有数据。
让我们看一下Json的每个元素。
关联数组
{}是一个关联数组,以key:value的形式描述数据。如果有多个此类数据,请用逗号(,)将其连接。
{ HP:10, ATK:29, name: "enemy1" }, { HP:13, ATK:43, name: "enemy2" }
数组
[]以保留顺序保存数组中相同类型的数据。如果有多个数据,请将它们与(,)连接。[1,2,3]
组合
JSON仅具有上述结构。因此,很难记住,
通过组合以上内容,可以分层地描述复杂信息。
例如,让我们用JSON表示多个敌人的信息。
{ enemies:[ { name: "enemy1" HP:10, ATK:29, }, { name: "enemy2" HP:13, ATK:43, } ] }
上面是敌人信息的JSON表示形式。
JSON的好处
现在,您已经对JSON有了一个概述,您可能会认为CSV(如果您不了解,可以考虑一下Excell)就可以了。
确实如此。但是,JSON的最大优点是,即使具有不规则结构的数据也可以轻松表示。
例如,在CSV的情况下,由于简单地按顺序排列数据,因此不描述这些关系。
如果特定元素丢失或奇怪,则无法检测到。
例如,它看起来像这样
name,flag enemy1,on enemy2,off enemy3
上面是敌人及其标志的CSV描述。
如果设置了标志,则将其打开;如果未设置,则将其设置为关闭。我不敢在敌人3的旗帜上写任何东西。
以这样的速度,我不知道敌人3的标志是什么,但这对csv的描述很好。
但是,当将其作为游戏数据传递时,情况就不同了。直到执行并加载数据后,才知道此数据丢失。结果,如果发生错误并停止错误会更好,但是如果出现问题,则需要大量时间来查找原因。如您所见,在CSV中,\”flag\”由于它没有对应于开/关的信息,因此它可能会意外移动。
JSON相对于上面的优势在于它可以表示数据的结构。
您可以通过将键和值作为一组来描述关系。
因此,如果没有任何价值,您可以放心结构已损坏,并且会立即引发错误。
如何在Untiy中使用Json Utility
现在,您已经对JSON有了一个概述,让我们看一下如何在Untiy中使用JSON。
Unity官员提供了处理JSON的对象杰森公司使用。
这很快,但是它有一些局限性和不足的功能。让我们看看这些与实际用法。
类到JSON的转换
首先,让我们看看如何将类转换为JSON格式。
using System.Collections; using System.Collections.Generic; using UnityEngine; public class jsonClass : MonoBehaviour { // Use this for initialization public int HP = 1; public int ATK = 3; public string name = "hello"; void Start () { Debug.Log(JsonUtility.ToJson(this)); } // Update is called once per frame void Update () { } }
这是整个代码。
public int HP = 1; public int ATK = 3; public string name = \"hello\";
这部分定义了类的字段。您说过JSON有一个键和一个值作为集合。
对于JsonUtility,变量名称:存储在变量中的值
通过该方法进行转换。
Debug.Log(JsonUtility.ToJson(this));
上面的JsonUtility.ToJson是一个将类转换为Json并将该类的实例作为参数的函数。
在这种情况下,实际运行的jsonClass会在该类内部进行转换,因此它会以此方式传递。
为了确认这一点,我使用Debug.log将其输出到控制台屏幕。
尝试将此脚本粘贴到合适的对象中并运行它。
从杰森上课
从Json转换为类有两种方法。这也有一些烦人的问题。
让我们用实际的例子来解释。
生成类并返回实例
jsonUtility类
using System.Collections; using System.Collections.Generic; using UnityEngine; using JsonData; public class JsonClass : MonoBehaviour { // Use this for initialization public int HP = 1; public int ATK = 3; public string name = "hello"; void Start () { JsonDataClass jsonDataClass; string jsonString = "{\"HP\":12,\"ATK\":6,\"name\":\"asdf\"}"; jsonDataClass = 杰森公司.FromJson<JsonDataClass>(jsonString); Debug.Log(jsonDataClass.ATK); Debug.Log(jsonDataClass.name); Debug.Log(jsonDataClass.HP); } // Update is called once per frame void Update () { } }
资料储存类别
namespace JsonData { public class JsonDataClass { public int HP; public int ATK; public string name; } }
它采用json格式的字符串,并创建其类的新实例。
首先,作为前提,这次我们将根据json生成一个类,因此让我们首先定义一个专用于Json数据存储的类。
就是这个JsonDataClass。
让我们实际看一下代码。请参阅jsonUtility使用的类。
string jsonString = "{\"HP\":12,\"ATK\":6,\"name\":\"asdf\"}";
首先,创建一个Json字符串。我存储了价值,
jsonDataClass = 杰森公司.FromJson<JsonDataClass>(jsonString);
C#只能先定义类型,所以
您必须提供要生成的类的类型信息。
因此,给出泛型生成的类的类型信息。然后将json字符串作为参数传递,以将值放入生成的类中。
请检查debug.log作为试用版。您可以看到该值已存储。
但是,此功能存在严重缺陷。
最重要的是,如果创建类实例的目标继承自MonoBehavior,类生成失败。
我将省略它,因为详细解释很长,但是在使用Unity函数时,必须继承MonoBehavior,并且这种继承会导致各种限制。
例如,当尝试创建实例或读取数据时,该操作将因此失败。
这可能有点令人困惑,但是问题是“立即上新班级”。因此,由于它已经生成或超出范围,所以即使您在上一个示例或以下示例中将MonoBehaivor定位为目标,它也可以正常工作。
覆盖现有变量
using System.Collections; using System.Collections.Generic; using UnityEngine; public class JsonClass : MonoBehaviour { // Use this for initialization public int HP = 1; public int ATK = 3; public string name = "hello"; void Start () { //JsonClass jsonClass = Instantiate(JsonClass); string jsonString = "{\"HP\":12,\"ATK\":6,\"name\":\"asdf\"}"; 杰森公司.FromJsonOverwrite(jsonString, this); Debug.Log(this.ATK); Debug.Log(this.name); Debug.Log(this.HP); } // Update is called once per frame void Update () { } }
作为Overwrite的名称,它存储从json提取的第二个参数的数据。
换句话说,它将通过覆盖现有变量的值来实现。
string jsonString = "{\"HP\":12,\"ATK\":6,\"name\":\"asdf\"}"; 杰森公司.FromJsonOverwrite(jsonString, this);
我像以前一样制作了一个json字符串,但是这次我将覆盖现有的json字符串而不创建一个新的json字符串。所以我没有在泛型中指定类型
相反,它包含覆盖Json字符串的类的实例。
当执行此函数时,它不返回返回值,而是通过引用传递来重写第二个参数的实例。
请尝试检查Debug.log的内容。它已被更改。
如果不转换为Json
到目前为止,我已经解释了一般用法,但是我还将介绍一些注意事项,例如无法将其转换为json时。最大的警告是,即使无法将类中的字段转换为Json
杰森公司不会引发错误并忽略它。结果,它无意地表现并导致错误,并且非常麻烦,因为除非执行它才能确定。
因此,我将说明不进行转换的情况。
最重要的是,如果变量无法序列化,则无法转换。
我将省略对序列化的解释,因为它会很长,但是简单来说,可以将其视为将类的数据(二进制)转换为可以存储数据的形式(文本)。
详细规格
//docs.unity3d.com/ja/current/Manual/script-Serialization.html
//docs.unity3d.com/ja/current/Manual/JSONSerialization.html
请阅读以上两个。但是,这很麻烦,因此我将至少列出那些移动的对象。
粗略地说,如果满足以下条件,它将不会转换。
- 私人的(例外)
- const
- 静态的
- 非序列化字段
- 只读
- 字典
- 抽象类
- 等等
但是,对于私有,您可以通过添加[SerializeField]来序列化该字段。
检查要点如下。
- 1.访问级别
- 2.类型可序列化吗?
-
3.如果使用ToJson函数,是否继承自MonoBehavior?
是重点。如果它不能转换为Json,请检查以上内容。
其他图书馆
无论多快,都有一些限制很烦人。特别地,根据情况使用诸如字典的数据类型是困难的。
我还将介绍另一个Json库。
Json.NET
一个用于处理C#中著名的Json的库。
这是字典也可以使用因此,如果遇到麻烦,可以选择它。
处理速度本身比Json Utility慢,但是我认为您可以正常使用它,除非您在需要性能的环境中。
实际例子
最后,让我们考虑一个简单游戏的实现。在这种情况下,请考虑一款新颖的游戏。
这次,让我们考虑一下这些因素。
- 站立图片
- 对话
- 背景
考虑一个JSON,它包含一个动作(每次加载背景,站立图片和对话)的每条信息。
首先要考虑的是拥有什么信息以及采用什么形式。
例如
我在本地具有背景,那么为什么不指向本地文件名呢?
让我们对站立图片上的信息进行相同的操作。
让我们按原样加载行
让我们考虑一下您拥有什么样的信息,以及如何接收和处理它。
因此,此类和JSON的结构为
资料储存类别
// ローカルの背景ファイル名 public string background; // ローカルの立ち絵ファイル名 public string standChara; // 对话の文字列 public string[] serif;
比方说
让我们考虑一个实际使用该数据的类。
必须继承MonoBehavior,因为该类实际上反映了Unity中的数据。
最重要的是,您可以访问Ui和图像等对象,因此
使用的班级
// 对话表示用のゲームオブジェクト例 public GameObject UIText // 背景表示用のゲームオブジェクト例 public GameObject UIImage // 站立图片キャラのゲームオブジェクト例 public GameObject UIChara void Start () { string jsonString = "{\"background\":\"normal\",\"standChara\":[\"chara_plate\"],\"serif\":[\"hello\",\"test\"]}"; NovelData novelData = 杰森公司.FromJson<NovelData>(jsonString); // 画像を変更したり・・・・ }
就像那样。
我要考虑的是
string jsonString = "{\"background\":\"normal\",\"standChara\":[\"chara_plate\"],\"serif\":[\"hello\",\"test\"]}";
这是其中的一部分。在此类中一个接一个地编写json是一件愚蠢的事,因此您必须考虑加载或生成Json。换句话说,您可以自己创建一个新颖的游戏引擎。
如何加载JSON数据
最后,我将解释如何加载json。
其中有几种,但是这次我们将介绍将数据放置在服务器上和本地的典型示例。
API
JSON是REST API。当您点击URL时,REST API将以JSON格式返回结果。因此,在上述新颖游戏引擎的示例中,数据存储在另一台服务器上,并通过API以json格式获取。
如您所见,这假定您正在与服务器上的数据进行通信。
另外,由于这种结构很重要,因此有许多示例。
如果您想与服务器通信,则可以在练习后尝试使其与服务器通信。
本地文件
第二种方法是将JSON作为文件存储在本地并读取。但是,即使JSON可以在结构上处理数据,但手动无休止地编辑JSON还是很麻烦的。因此,存在一种以人类易于处理的数据格式编辑数据并将其最终转换为JSON的方法。最著名的示例是将在Excel中以CSV格式编辑的文件转换为json格式。这样做的好处是可以在本地完成,因此轻松进行测试和编辑就不会麻烦。如果要决定设计和功能,让我们在本地进行实验。
概要
怎么样。 JSON是一种非常易于使用的数据处理工具。但是,这就是为什么JSON结构的设计以及应该使用它的部分变得非常重要的原因。顺便说一下,实现示例的新颖游戏的示例是我上大学时由作者制作的。如果按原样放置,它将被加载很多次,并且有些部分可能是反复试验的结果,因此,让我们通过根据自己的游戏重复进行练习来获得最佳实践。