《JSON数据结构》 |
版本 |
作者 |
参与者 |
完成日期 |
备注 |
Data_JSON_V01_1.0 |
严立钻 |
|
2018.08.24 |
|
|
|
|
|
|
++++一个好用的JSON在线编辑:http://www.kjson.com/jsoneditor/?f=1
##《JSON数据结构》发布说明:
++++“JSON数据结构”是一种轻量级的数据交换格式,也是一种重要的本地数据存储方式;在Unity中还有PlayerPrefabs、XML等类型;
++++“JSON数据结构”:在Unity中使用“LitJson.dll”和“System.Json.dll”两个类库;
##《JSON数据结构》目录
#第一篇:快速入门篇
#第二篇:中级进阶篇
#第三篇:高级成魔篇
#第一篇:快速入门篇 |
#第一篇:快速入门篇
++++A.1、前言
++++A.2、JSON简介
++++A.3、JSON基本结构
++++A.4、JSON开发
++++A.5、JSON简单示例
++++A.6、Unity中JSON应用
++++A.7、立钻哥哥带您JSON实战
##A.1、前言 |
++A.1、前言
++++使用Unity做游戏开发,包括VR游戏等联网功能是必不可少的,所以跟服务器打交道也就必不可少;
++++其实在其他语言开发环境中也需要与服务器打交道,而所使用的数据格式都是一样的;
++++我们可以不会搭建服务器的业务逻辑,但是服务器返回给客户端的数据,是我们必须要会的;
##A.2、JSON简介 |
++A.2、JSON简介
++++JSON是纯文本的;
++++JSON是一种轻量级的数据交换格式;
++++JSON具有层次结构(值中存在值);
##A.3、JSON基本结构 |
++A.3、JSON基本结构
++++1、数据在键值对;
++++2、数据由逗号分隔;
++++3、花括号保存对象;
++++4、方括号保存数组;
++用{}包裹,用名称/值来表示对象中的一个属性
{ “name” : ”立钻哥哥”, “age” : “18” }; |
++[]包裹,表示一个对象属性下面的多个元素内容
{ “Persons” : [ { “name” : “立钻哥哥”, “age” : “28” }, { “name” : “小珏妹妹”, “age” : “18” } ] } |
++一段服务器返回的数据格式参考
{ “name” : “立钻哥哥”, “age” : 28, “height” : 1.90, “school” : { “name” : “清华大学”, “address” : “北京海淀” }, “photos” : [ { “icon” : “helloworld.png”, “time” : “2017-08-08” }, { “icon” : “nice.png”, “time” : “2017-09-09” }, { “icon” : “lovezuanzuan.png”, “time” : “2018-08-08” } ] } |
##A.4、JSON开发 |
++A.4、JSON开发
++++立钻哥哥:使用两种类库:System.Json、LitJson等;
++[System.Json]:便于JSON生成
++++[JsonArray]:是零个或多个JsonValue对象的有序序列;
++++[JsonObject]:是一个无序的零个或更多的键/值对的集合;
++++[JsonValue]:具体一个Value值;
++++{}大括号:一对一对
//创建一个JSON对象,相当于一个大括号 JsonObject jsonTransform = new JsonObject();
|
//创建一个JSON值对象,存储一个Value JsonValue jsonPosition = “10, 20, 30”;
|
//JSON对象,也就是大括号,添加一个key:value jsonTransform.Add(“position”, jsonPosition);
|
//打印结果 Debug.Log(jsonTransfrom.ToString());
|
显示:{“position”:”10,20,30”} |
++++[]中括号:一个一个
//定义一个值数组,用来存储,中括号中的一个个的值 JsonValue[] rotationXYZ = new JsonValue[]{20, 30, 40};
|
//将这个数组中的一个个的值放到JsonArray数组对象中 JsonArray jsonRotation = new JsonArray(rotationXYZ);
|
//一个JsonArray对象,也可以是一个Value,所以可以用jsonTransform来Add jsonTransform.Add(“rotation”, jsonRotation);
|
//打印结果 Debug.Log(jsonTransform);
|
结果显示: {“position”:”10,20,30”, “rotation”:[20,30,40]} |
++++jsonArray中添加对象对象
//jsonArray中添加对象(大括号中包含的所有内容) JsonObject x = new JsonObject(); x.Add(“x”, 10);
JsonObject y = new JsonObject(); y.Add(“y”, 20);
JsonObject z = new JsonObject(); z.Add(“z”, 30);
|
//实例一个jsonValues数组(所有类型都可以转换成jsonValue) JsonValue[] scaleXYZ = new JsonValue[]{ x, y, z };
|
//将实例好的数组,添加到jsonArray对象中,形成一个jsonArray对象(作用:给这个整体,添加一个中括号[]) JsonArray jsonScale = new JsonArray(scaleXYZ);
|
//将这个整体,放入到jsonTransform中 jsonTransform.Add(“scale”, jsonScale);
|
//打印结果 Debug.Log(jsonTransform);
|
结果显示: {“position”:”10,20,30”, “rotation”:[20,30,40], “scale”:[{“x”:10}, {“y”:20}, {“z”:30}]}
|
++[LitJson]:便于JSON解析
++++[JsonMapper.ToJson]:把对象转化成JSON格式字符串;
++++[JsonMapper.ToObject]:把JSON格式字符串转化成对象;
++++把对象转换成JSON
public class MyPerson{ public string Name{ get; set; } public int Age{ get; set; } } //立钻哥哥:public class MyPerson{}
MyPerson myPer = new MyPerson(){ Name = “立钻哥哥”, Age = “28” }; ++++结果:{“Name”:”立钻哥哥”, “Age”:28}
|
MyPerson yanlz = new MyPerson(); yanlz.Name = “立钻哥哥”; yanlz.Age = 28; string jsonYanlz = JsonMapper.ToJson(yanlz);
Debug.Log(jsonYanlz); |
++++把JSON转化成对象(非泛型)
string json = @”{ “mxy”:{ “name”:”Albert”, “artist”:”Sing Song”, “year”:1999, “tracks”:[“Bistu”, “CSS”, “立钻哥哥”] } } ”;
|
JsonData data = JsonMapper.ToObject(json); Debug.Log(“立钻哥哥: mxy’s name:” + data[“mxy”][“name”]);
string artist = (string)data[“mxy”][“artist”]; int year = (int)data[“mxy”][“year”]; Debug.Log(“立钻哥哥:Recorded by” + artist + “ in ” + year); Debug.Log(“立钻哥哥:First track: ” + data[“mxy”][“tracks”][0]); |
++网络传输中,JSON返回数据示意图
++++[客户端]:发送请求;
++++[服务器]:返回数据(JSON数据);
++++[客户端]:C#对象(字典数组等);
++JSON和XML的比较
|
JSON |
XML |
语法格式 |
数组与键值对(字典/对象) |
用节点表示的树形结构 |
数据量 |
轻量级 |
文件庞大 |
可读性 |
较弱 |
较强 |
解析难度 |
相对容易 |
相对麻烦 |
执行效率 |
较高 |
较低 |
++立钻哥哥:同一份数据,既可以用JSON来表示,也可以用XML来表示;JSON的体积小于XML,所以服务器返回给移动端的数据格式以JSON居多,而对于客户端两者都可以; |
##A.5、JSON简单示例 |
++A.5、JSON简单示例
++++A.5.1、编写代码,完成一个JsonObject储存英雄信息?
++++A.5.2、使用LitJson格式保存一个角色的transform?
++++A.5.3、解析服务器返回的JSON数据?
###A.5.1、编写代码,完成一个JsonObject储存英雄信息? |
++A.5.1、编写代码,完成一个JsonObject储存英雄信息?
编写代码,完成一个JsonObject储存以下信息:
--英雄名称:立钻哥哥;
--生命值:800.00;
--攻击伤害:66.88;
--技能1:被动技能-出血;
--技能2:Q技能-大杀四方(冷却时间:9/8/7/6/5 消耗:30法力)
--技能3:W技能-致残打击(冷却时间:9/8/7/6/5 消耗:30法力)
--技能4:E技能-无情铁手(冷却时间:24/21/18/15/12)
--技能5:R技能-断头台(冷却时间:120/100/80 消耗:100/100/0法力)
++++立钻哥哥:
++创建空物体改名GameObject,并挂载脚本CreateJsonScript
using System.Json; using System.IO; using UnityEditor;
public class CreateJsonScript : MonoBehaviour{ //Use this for initialization void Start(){ CreateJson(); }
void CreateJson(){ JsonObject hero = new JsonObject(); //创建json对象
//添加键值对 hero.Add(“英雄名称”, “立钻哥哥”); hero.Add(“生命值”, 800.00); hero.Add(“攻击伤害”, 66.88);
//添加技能组 JsonObject bSkill = new JsonObject(); bSkill.Add(“被动技能”, “出血”);
JsonObject qSkill = new JsonObject(); qSkill.Add(“Q技能”, “大杀四方”); qSkill.Add(“冷却时间”, new JsonArray(9,8,7,6,5)); //将jsonArray当做value qSkill.Add(“消耗”, 30);
JsonObject wSkill = new JsonObject(); wSkill.Add(“W技能”, “致残打击”); wSkill.Add(“冷却时间”, new JsonArray(9,8,7,6,5)); wSkill.Add(“消耗”, 30);
JsonObject eSkill = new JsonObject(); eSkill.Add(“E技能”, “无情铁手”); eSkill.Add(“冷却时间”, new JsonArray(24, 21, 18, 15, 12));
hero.Add(“技能” , new JsonArray(bSkill, qSkill, wSkill, eSkill));
//保存json对象 string path = Application.dataPath + “/YanlzDemo/myLoL.txt”; Debug.Log(path); StreamWriter writer = new StreamWriter(path); hero.Save(writer); writer.AutoFlush = true; writer.Close();
AssetDatabase.Refresh();
} //立钻哥哥:void CreateJson(){}
} //立钻哥哥:public class CreateJsonScript:MonoBehaviour{} |
###A.5.2、使用LitJson格式保存一个角色的transform? |
++A.5.2、使用LitJson格式保存一个角色的transform?
使用LitJson格式保存一个角色的transform。(自己定义一个transform,然后保存到文件,然后再读取出来)
++++立钻哥哥:
++自己定义一个transform,然后保存到文件MyTransform.txt
{ “position” : {“x”:10, “y”:10, “z”:3.2}, “rotation” : {“x”:20.0, “y”:10.0, “z”:3}, “scale” : {“x”:1, “y”:3, “z”:3}, }; |
++在场景中创建空物体并添加脚本MyParseJson
using System.IO; using LitJson;
public class MyParseJson : MonoBehaviour{ //Use this for initialization void Start(){ ReadJson(); }
void ReadJson(){ //根据文件路径读取json格式字符串 string path = Application.dataPath + “/YanlzDemo/MyTransform.txt”;
StreamReader reader = new StreamReader(path); string jsonStr = reader.ReadToEnd(); reader.Close();
//将json格式的字符串转成jsondata JsonData data = JsonMapper.ToObject(jsonStr);
//获取内容 string x = data[“position”][“x”].ToString(); string y = data[“position”][“y”].ToString(); string z = data[“position”][“z”].ToString();
Debug.Log(x); Debug.Log(y); Debug.Log(z); } //立钻哥哥:void ReadJson(){}
} //立钻哥哥:public class MyParseJson:MonoBehaviour{} |
###A.5.3、解析服务器返回的JSON数据? |
++A.5.3、解析服务器返回的JSON数据?
[ {“id”:10, “Name”:”立钻哥哥”, “age”:28}, {“id”:20, “Name”:”小珏妹妹”, “age”:20}, {“id”:30, “Name”:”小飞弟弟”, “age”:18} ]
|
++++立钻哥哥:
++使用LitJson进行解析
//解析出我们可以识别的对象 string path = “Assets/Resources/MyTextFile.txt”; string textOne = File.ReadAllText(path); JsonData data1 = JsonMapper.ToObject(textOne);
for(int i = 0; i < data1.Count; i++){ JsonData nameValue = data1[i][“Name”]; NameText.text = nameValue.ToString();
JsonData IDValue = data1[i][“id”]; IDText.text = IDValue.ToString();
JsonData AgeValue = data1[i][“age”]; AgeText.text = AgeValue.ToString();
Debug.Log(nameValue); Debug.Log(“立钻哥哥:名字是:” + NameText + “ID: ” + IDText); } |
++解析出来并给对象赋值
MyPerson[] myPer = new MyPerson[]{ p1 = new MyPerson(), p2 = new MyPerson(), p3 = new MyPerson() };
string path = “Assets/Resources/MyTextFile.txt”; string textOne = File.ReadAllText(path); JsonData data = JsonMapper.ToObject(textOne); Debug.Log(myPer.Length);
for(int i = 0; i < data.Count; i++){ JsonData idValue = data[i][“id”]; myPer[i].id = int.Parse(idValue.ToString());
JsonData ageValue = data[i][“age”]; myPer[i].age = int.Parse(ageValue.ToString());
JsonData nameValue = data[i][“Name”]; myPer[i].name = nameValue.ToString();
Debug.Log(“立钻哥哥:name:” + nameValue.ToString()); } |
##A.6、Unity中JSON应用 |
++A.6、Unity中JSON应用
++++立钻哥哥:通过一个Unity中JSON的应用,熟悉JSON;
++++A.6.1、json.txt
++++A.6.2、CubeItem.cs
++++A.6.3、CubeManager.cs
++++A.6.4、CubeTest.cs
++++A.6.5、JsonDemo.cs
++++A.6.6、Person.cs
###A.6.1、json.txt |
++A.6.1、json.txt
++++立钻哥哥:\Assets\Resources\json.txt
{“PosX”:”0”, “PosY”:”0”, “PosZ”:”0”} |
###A.6.2、CubeItem.cs |
++A.6.2、CubeItem.cs
++++立钻哥哥:\Assets\Scripts\CubeItem.cs
using UnityEngine; using System.Collections;
public class CubeItem{ public string PosX{ get; set; } public string PosY{ get; set; } public string PosZ{ get; set; }
public CubeItem(){ }
public CubeItem(string x, string y, string z){ this.PosX = x; this.PosY = y; this.PosZ = z; }
public override string ToString(){ return string.Format(“立钻哥哥:X:” + PosX + “ Y:” + PosY + “ Z:” + PosZ); }
} //立钻哥哥:public class CubeItem{} |
###A.6.3、CubeManager.cs |
++A.6.3、CubeManager.cs
++++立钻哥哥:\Assets\Scripts\CubeManager.cs
using UnityEngine; using System.Collections; using LitJson; using System.Collections.Generic; using System; using System.IO;
public class CubeManager : MonoBehaviour{ private Transform m_Transform; //父物体的Transform private Transform[] allCubeTran; //所有子物体的Transform private List<CubeItem> cubeList; //Cube对象 private List<CubeItem> posList; //json数据里的对象 private string jsonPath = null; private GameObject cubePrefab;
void Start(){ m_Transform = GetComponent<Transform>(); cubeList = new List<CubeItem>(); posList = new List<CubeItem>(); jsonPath = Application.dataPath + “/Resources/json.txt”; cubePrefab = Resources.Load<GameObject>(“Prefabs/Cube”); }
void Update(){ if(Input.GetKeyDown(KeyCode.A)){ ObjectToJson(); }
if(Input.GetKeyDown(KeyCode.B)){ JsonToObject(); } }
//对象转Json字符串数据 void ObjectToJson(){ cubeList.Clear(); allCubeTran = m_Transform.GetComponentsInChildren<Transform>();
for(int i = 1; i < allCubeTran.Length; i++){ //print(allCubeTran[i].position); Vector3 pos = allCubeTran[i].position; CubeItem item = new CubeItem( Math.Round(pos.x, 2).ToString(), Math.Round(pos.y, 2).ToString(), Math.Round(pos.z, 2).ToString() ); cubeList.Add(item); }
string str = JsonMapper.ToJson(cubeList); print(str);
//IO持久化json数据,把它以文本的形式存储在本地中 StreamWriter sw = new StreamWriter(jsonPath); sw.Write(str); sw.Close(); } //立钻哥哥:void ObjectToJson(){}
//Json数据转对象 void JsonToObject(){ //读取Json数据信息 TextAsset textAsset = Resources.Load<TextAsset>(“json”); print(textAsset.text);
//把数据转换为对象 JsonData data = JsonMapper.ToObject(textAsset.text); for(int i = 0; i < data.Count; i++){ //print(data[i].ToJson()); //指定对象接收数据 CubeItem item = JsonMapper.ToObject<CubeItem>(data[i].ToJson()); posList.Add(item); }
for(int i = 0; i < posList.Count; i++){ //print(posList[i].ToString()); Vector3 pos = new Vector3( float.Parse(posList[i].PosX), float.Parse(posList[i].PosY), float.Parse(posList[i].PosZ) );
GameObject.Instantiate(cubePrefab, pos, Quaternion.identity, m_Transform); }
} //立钻哥哥:void JsonToObject(){}
} //立钻哥哥:public class CubeManager:MonoBehaviour{} |
###A.6.4、CubeTest.cs |
++A.6.4、CubeTest.cs
++++立钻哥哥:\Assets\Scripts\CubeTest.cs
using UnityEngine; using System.Collections; using LitJson;
public class CubeTest : MonoBehaviour{ private Transform m_Transform;
void Start(){ m_Transform = GetComponent<Transform>(); Vector3 pos = m_Transform.position;
//string str = JsonMapper.ToJson(pos); //print(str); //LitJson不支持float //CubeItem item = new CubeItem(pos.x, pos.y, pos.z); //string str = JsonMapper.ToJson(item); //print(str); }
} //立钻哥哥:public class CubeTest:MonoBehaviour{} |
###A.6.5、JsonDemo.cs |
++A.6.5、JsonDemo.cs
++++立钻哥哥:\Assets\Scripts\JsonDemo.cs
using UnityEngine; using System.Collections; using LitJson; using System.Collections.Generic;
public class JsonDemo : MonoBehaviour{ private List<Person> persons; //Persons对象 private List<Person> personsOne; //Json数据里的对象
void Start(){ ChangeSingleObject(); //立钻哥哥:单个对象转换 ChangeMultiObjects(); //立钻哥哥:多个对象转换 } //立钻哥哥:void Start(){}
//单个对象转换 void ChangeSingleObject(){ //单个对象转Json Person p1 = new Person(“aaa”, 18, “bbb”); string str = JsonMapper.ToJson(p1); print(str);
//Json转当个对象 Person p2 = JsonMapper.ToObject<Person>(str); print(p2.ToString()); }
//多个对象转换 void ChangeMultiObjects(){ //多个对象转Json persons = new List<Person>(); Person p1 = new Person(“aaa”, 18, “bbb”); Person p2 = new Person(“bbb”, 20, “ddd”); persons.Add(p1); persons.Add(p2); string str = JsonMapper.ToJson(persons); //print(str);
//Json转多个对象 personOne = new List<Person>(); JsonData data = JsonMapper.ToObject(str); for(int i = 0; i < data.Count; i++){ //print(data.ToJson()); Person item = JsonMapper.ToObject<Person>(data[i].ToJson()); personOne.Add(item); }
for(int i = 0; i < personOne.Count; i++){ print(personsOne[i].ToString()); } } //立钻哥哥:void ChangeMultiObjects(){}
} //立钻哥哥:public class JsonDemo:MonoBehaviour{} |
###A.6.6、Person.cs |
++A.6.6、Person.cs
++++立钻哥哥:\Assets\Scripts\Person.cs
using UnityEngine; using System.Collections;
public class Person{ public string Name{ get; set; } public int Age{ get; set; } public string Address{ get; set; }
public Person(){ }
public Person(string name, int age, string address){ this.Name = name; this.Age = age; this.Address = address; }
public override string ToString(){ return string.Format(“名字” + Name + ”年龄” + Age + “住址” + Address); }
} //立钻哥哥:public class Person{} |
##A.7、立钻哥哥带您JSON实战 |
++A.7、立钻哥哥带您JSON实战
++++A.7.1、Json在Unity中的使用
++++A.7.2、Unity读写Json数据:LitJSON
++++A.7.3、Unity中生成JSON以及对应的解析方法
++++A.7.4、Unity中使用Json解析字符串
++++A.7.5、Unity常用的几种解析Json方式
++++A.7.6、Unity的Json解析(读取Json文件)
++++A.7.7、Unity解析Json字符串(LitJson.dll)
###A.7.1、Json在Unity中的使用 |
++A.7.1、Json在Unity中的使用
++++立钻哥哥:JSON(JavaScript Object Notation)是一种轻量级的数据交换格式。它基于ECMAScript的一个子集;JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++、C#、Java、JavaScript、Perl、Python等);这些特性使JSON成为理想的数据交换语言;易于人阅读和编写,同时也易于机器解析和生成(一般用于提升网络传输速率);
++JSON语法规则
++++数据在键值对中;
++++数据由逗号分隔;
++++花括号保存对象;
++++方括号保存数组;
++JSON的结构
++++【对象】:对象在json中表示为”{}”括起来的内容,数据结构为{key:value, key:value, ...}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为[对象.key]获取属性值,这个属性值的类型可以是数字、字符串、数组、对象几种;
++++【数组】:数组在json中是中括号“[]”括起来的内容,数据结构为[“java”, “javascript”, “vb”, ...],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是数字、字符串、数组、对象几种;
++JSON在Unity3d中的使用
++++【JsonUtility】:JsonUtility是Unity5.3后新增的内容,有时会出现莫名其妙的错误;
--[JsonUtility.FromJson()]:把json字符串转成对象;
--[JsonUtility.ToJson()]:把对象转成json字符串;
++++【LitJson】:LitJson是一个Json的开源项目,这个比较稳定,推荐使用;
--[JsonMapper.ToObject()]:把json字符串转成对象;
--[JsonMapper.ToJson()]:把对象转成json字符串;
--使用时:dll文件要放在Plugins文件夹下,代码访问时要引用命名空间:using LitJson;
###A.7.2、Unity读写Json数据:LitJSON |
++A.7.2、Unity读写Json数据:LitJSON
++++立钻哥哥:JSON是一个简单的,但功能强大的序列化数据格式;它定义了简单的类型,如布尔,数(int和float)和字符串,和几个数据结构:List和Dictionary;
++++LitJson是用C#编写的,它的目的是要小,快速,易用;它使用Mono框架;
++安装LitJson
++++立钻哥哥:将LitJson编译好的dll文件通过Import New Asset的方式导入到项目中,再使用Using LitJSON; 即可使用JsonMapper类中的简便方法;
++将JSON转换为Object并可逆向转化
++++立钻哥哥:为了在.Net程序中使用JSON格式的数据,使用JSON文本生成一个特定的类的一个新实例;为了匹配类的格式,一般存储的JSON字符串是一个字典;
++++为了将对象序列化为JSON字符串,LitJSON包引入了JsonMapper类,它提供了两个用于做到:JSON转化为Object和Object转化为JSON的主要方法;
--这两个方法:JsonMapper.ToJson()、JsonMapper.ToObject();
++一个简单的JsonMapper的例子(使用泛型JsonMapper.ToObject
using LitJson; using System;
public class Person{ public string Name{ get; set; } public int Age{ get; set; } public DateTime Birthday{ get; set; } } //立钻哥哥:public class Person{}
public class JsonSample{ public static void Main(){ PersonToJson(); JsonToPerson(); }
public static void PersonToJson(){ Person bill = new Person(); bill.Name = “立钻哥哥”; bill.Age = 28; bill.Birthday = new DateTime(1990, 08, 08);
string json_bill = JsonMapper.ToJson(bill); Console.WriteLine(json_bill); }
public static void JsonToPerson(){ string json = @”{ “”Name””:””立钻哥哥””, “”Age”” : 57, “”Birthday”” : “08/08/1990 00:00:00” }”;
Person yanlz = JsonMapper.ToObject<Person>(json); Console.WriteLine(“立钻哥哥:age:{0}”, yanlz.Age); }
} //立钻哥哥:public class JsonSample{}
|
++输出: {“Name”:”立钻哥哥”, “Age”:28, “Birthday”:”08/08/1990 00:00:00”} 立钻哥哥:age: 28 |
++立钻哥哥:ToObject方法有一个泛型参数,来指定返回的某种特定的数据类型: --JsonMapper.ToObject<T>(); --Person yanlz = JsonMapper.ToObject<Person>(json); |
++使用非泛型的JsonMapper.ToObject()
using LitJson; using System;
public class JsonSample{ public static void Main(){ string json = @”{ ““album””:{ “”name”” : “立钻哥哥的专辑”, “”artist”” : “立钻哥哥”, “”year”” : 2018, “”tracks”” : [ “”爱在路上””, “为爱痴狂”, “世上只有妈妈好” ] } }”;
LoadAlbumData(json); } //立钻哥哥:public static void Main(){}
public static void LoadAlbumData(string json_text){ Console.WriteLine(“立钻哥哥:JSON string: {0}”, json_text);
JsonData data = JsonMapper.ToObject(json_text); string artist = (string)data[“album”][“artist”]; int year = (int)data[“album”][“year”];
Console.WriteLine(“立钻哥哥:Album’s name:{0} ”, data[“album”][“name”]); Console.WriteLine(“立钻哥哥:Recorded by {0} in {1}”, artist, year); Console.WriteLine(“立钻哥哥:First track: {0}”, data[“album”][“tracks”][0]); } //立钻哥哥:public static void LoadAlbumData(){}
} //立钻哥哥:public class JsonSample{}
|
++输出: 立钻哥哥:JSON string: { “album” : { “name” : “立钻哥哥的专辑”, “artist” : “立钻哥哥”, “year” : 2018, “tracks” : [ “爱在路上”, “为爱痴狂”, “世上只有妈妈” ] } } Album’s name: 立钻哥哥的专辑 Recorded by 立钻哥哥 in 2018 First track: 爱在路上
|
++立钻哥哥:当不存在特定的JSON数据类时,它将返回一个JsonData实例; ++++JSONData是一种通用型可以保存任何数据类型,包括:List和Dictionary; |
++Reader和Writer(使用Stream的方式处理JSON数据)
using LitJson; using System;
public class DataReader{ public static void Main(){ string sample = @”{ “”name”” : “立钻哥哥”, “”age”” : 28, “”awake”” : true, “”n”” : 2018.0828, “”note”” : [“”life””, “”is””, “”but””, “”a””, “”dream””] }”;
PrintJson(sample); } } //立钻哥哥:public class DataReader{}
public static void PrintJson(){ JsonReader reader = new JsonReader(json);
Console.WriteLine(“{0, 14} {1,10} {2,16}”, “Token”, “Value”, “Type”); Console.WriteLine(new string(‘-’, 42));
while(reader.Read()){ string type = reader.Value != null ? reader.Value.GetType().ToString() : “”; Console.WriteLine(“{0,14} {1, 10} {2, 16}”, reader.Token, reader.Value, type); }
} //立钻哥哥:public static void PrintJson(){}
|
++输出 Token Value Type ObjectStart PropertyName name System.String String 立钻哥哥 System.String PropertyName age System.String Int 28 System.Int32 PropertyName awake System.String Boolean True System.Boolean PropertyName n System.String Double 2018.0828 System.Double PropertyName note System.String ArrayStart String life System.String String is System.String String but System.String String a System.String String dream System.String ArrayEnd ObjectEnd
|
++立钻哥哥:一些人喜欢使用stream的方式处理JSON数据,提供的接口是JsonReader和JsonWriter; ++++JsonMapper实际上是建立在以上两个类基础上的,可以把[JsonReader]和[JsonWriter]当成是[LitJson]的底层接口; |
###A.7.3、Unity中生成JSON以及对应的解析方法 |
++A.7.3、Unity中生成JSON以及对应的解析方法
++++立钻哥哥:将库脚本或动态库(LitJSON.dll)置在Assets目录下的Plugins文件夹中,因为Plugins文件夹中的脚本会先运行;
++Unity中生成JSON
using LitJson; //引用Json命名空间 using UnityEngine;
public class LitJsonDemo : MonoBehaviour{ //Use this for initialization void Start(){ JsonDataToJson(); JsonMapperToJson(); JsonWriterToJson(); } //立钻哥哥:void Start(){}
//JSON的生成 void JsonDataToJson(){ JsonData data = new JsonData(); data[“name”] = “立钻哥哥”;
//生成嵌套结构的json data[“info”] = new JsonData(); data[“info”][“age”] = 28; data[“info”][“sex”] = “男”;
string js1 = data.ToJson(); Debug.Log(js1);
//解析JSON JsonData jsdata1 = JsonMapper.ToObject(js1); Debug.Log(“立钻哥哥:解析json1 ” + jsdata1[“name”] + “ ” + jsdata1[“info”][“age”]);
//遍历JsonData的key(由于JsonData实现了IDictionary接口,可用foreach) IDictionary dic = jsdata1 as IDictionary; foreach(string item in dic.Keys){ Debug.Log(item); } }
//使用jsonMapper生成Json //此方法使用的前提是有一个玩家类 void JsonMapperToJson(){ Player play1 = new Player(); play1.Name = “小珏妹妹”; play1.Age = 18; play1.Sex = “女”;
string js2 = JsonMapper.ToJson(play1); Debug.Log(js2);
//解析Json Player play2 = JsonMapper.ToObject<Player>(js2); Debug.Log(“立钻哥哥:解析js2 ” + play2.name + “ ” + play2.age); }
//使用JsonWritter生成Json void JsonWriterToJson(){ JsonWriter js3 = new JsonWriter();
//对象类型的json js3.WriteObjectStart(); js3.WritePropertyName(“name”); js3.Write(“小飞弟弟”); js3.WritePropertyName(“age”); js3.Write(“15”); js3.WritePropertyName(“sex”); js3.Write(“男”); js3.WriteObjectEnd(); Debug.Log(js3.ToString());
JsonWriter js4 = new JsonWriter(); //生成数组型json js4.WriteArrayStart(); js4.Write(“成龙大哥”); js4.Write(“45”); js4.Write(“男”); js4.WriteArrayEnd(); Debug.Log(js4.ToString());
//======================================== //需要注意的是由开始就要写结束 JsonWriter js5 = new JsonWriter();
//生成数组含对象 js5.WriteArrayStart();
//第一个对象 js5.WriteObjectStart(); js5.WritePropertyName(“name”); js5.Write(“小飞弟弟”); js5.WritePropertyName(“age”); js5.Write(“15”); js5.WriteProperyName(“sex”); js5.Write(“男”); js5.WriteObjectEnd;
//第二个对象 js5.WriteObjectStart(); js5.WritePropertyName(“name”); js5.Write(“成龙大哥”); js5.WritePropertyName(“AGE”); js5.Write(“45”); js5.WritePropertyName(“SEX”); js5.Write(“男”); js5.WriteArrayEnd();
Debug.Log(js5.ToString());
//解析JSON(以js3为例) string json3 = js3.ToString(); JsonData jsdata3 = JsonMapper.ToObject(json3); Debug.Log(“立钻哥哥:解析js3 ” + jsdata3[“name”] + jsdata3[“age”] + jsdata3[“sex”]); } //立钻哥哥:void JsonWriterToJson(){}
//玩家类 public class Player{ public string Name{ get; set; } public int Age{ get; set; } public string Sex{ get; set; } } //立钻哥哥:public class Player{}
} //立钻哥哥:public class LitJsonDemo:MonoBehaviour{} |
++输出: {“name”:”立钻哥哥”, “info”:{“age”:28, “sex”:”男”}} //js1(JsonDataToJson) {“name”:”小珏妹妹”, “age”:18, ”sex”:”女”} //js2(JsonMapperToJson) {“name”:”小飞弟弟”, “age”:”15”, “sex”:”男”} //js3(JsonWriterToJson) {“成龙大哥”, “45”, “男”} //js4(JsonWriterToJson) [{“name”:”小飞弟弟”, “age”:”15”, “sex”:”男”}, {“name”:”成龙大哥”, “AGE”:”45”, “SEX”:”男”}] //js5 解析json1 立钻哥哥 28 name info 解析js2 小珏妹妹 18 解析js3 小飞弟弟 15 男 |
###A.7.4、Unity中使用Json解析字符串 |
++A.7.4、Unity中使用Json解析字符串
++++立钻哥哥:
++++A.7.4.1、将字典转换成字符串(JsonConvert.SerializeObject())
++++A.7.4.2、将Json字符串转成字典(JsonConvert.DeserializeObject
++++A.7.4.3、集合转成Json字符串(JsonConvert.SerializeObject())
++++A.7.4.4、将json字符串转成集合(JsonConvert.DeserializeObject>()
)
++++A.7.4.5、将字符串转成数组(JsonConvert.DeserializeObject())
++A.7.4.1、将字典转换成字符串(JsonConvert.SerializeObject())
private static void MyJson(){ //创建一个字典 Dictionary<string, int> dic = new Dictionary<string, int>{ {“yanlz01”, 001}, {“yanlz02”, 002}, {“yanlz03”, 003} };
//将字典转换成Json字符串 string json = JsonConvert.SerializeObject(dic, Newtonsoft.Json.Formatting.Indented);
} //立钻哥哥:private static void MyJson(){} |
++A.7.4.2、将Json字符串转成字典(JsonConvert.DeserializeObject
//创建一个新的字典保存结果 Dictionary<string, int> newDic = JsonConvert.DeserializeObject<Dictionary<string, int>>(json); |
++A.7.4.3、集合转成Json字符串(JsonConvert.SerializeObject())
List<List<string>> list = new List<List<string>>{ new List<string>{“yanlz01”, “yanlz02”, “yanlz03”}, new List<string>{“1001”, “1002”, “1003”} };
string json = JsonConvert.SerializeObject(list, Newtonsoft.Json.Formatting.Indented); |
++A.7.4.4、将json字符串转成集合(JsonConvert.DeserializeObject>())
List<List<string>> newList = JsonConvert.DeserializeObject<List<List<string>>>(json);
foreach(List<string> child0 in newList){ for(int i = 0; i < child0.Count; i++){ Debug.Log(child0[i]); } } |
++A.7.4.5、将字符串转成数组(JsonConvert.DeserializeObject())
string jsonArray = “[[” + “\”” + “yanlz01” + “\”” + “,1,2,1],[” + “\”” + “yanlz02” + “\”” + “,1,2,3” + “]]”; JArray jar = (JArray)JsonConvert.DeserializeObject(jsonArray);
for(int i = 0; i < jar.Count; i++){ ja = (JArray)JsonConvert.DeserializeObject(jar[i].ToString()); if(ja != null){ string name = ja[0].ToString(); string str1 = ja[1].ToString(); } } |
###A.7.5、Unity常用的几种解析Json方式 |
++A.7.5、Unity常用的几种解析Json方式
++++立钻哥哥:解析Jsno方式:LitJson、JsonUtility、Newtonsoft.Json等;
++++[LitJson]:比较流行,数据对象必须和Json一对一;
++++[JsonUtility]:Unity自带,不能解析复杂的Json;
++++[Newtonsoft.Json]:推荐使用,可以解析复杂的Json,不需要和Json字段一对一,灵活;
++[LitJson]
++++立钻哥哥:LitJson对Json解析提供多样化,可以解析成JsonData,也可以通过JsonMapper转成自定义的mode数据对象;
++++LitJson功能比较丰富,但是在通过JsonMapper转成自定的对象时,自定义对象的字段要和解析的Json字段一对一(Json里面的字段,自定义的对象一定要有),不然会解析失败;
++Json: string json = @”{ “”d”” : “”d””, “”album”” : { “”name”” : “”立钻哥哥的专辑””, “”artist”” : “”立钻哥哥””, “”year”” : 2018, “”tracks”” : [ “”为爱痴狂””, “”摇滚王子””, “"世上只有妈妈好"” ], “”tt”” : “”tt””, “”tracksOb”” : [ {“”trackOb”” : “”11””}, {“”trackOb”” : “”22””} ], “”bb”” : “”bb”” } }”;
|
++对应Json的mode有3个:MyOO,MyTestModel,MyTestModel2 public class MyOO{ public string d; pubic MyTestModel album; pubic string bb; } //立钻哥哥:public class MyOO{}
public class MyTestModel{ public string name; public string artist; public int year; public string[] tracks; public MyTestModel2[] tracksOb; } //立钻哥哥:public class MyTestModel{}
public class MyTestModel2{ public string trackOb; } //立钻哥哥:public class MyTestModel2{} |
++A.7.5.1、使用[LitJson]解析数据(JsonMapper.ToObject
++解析方法 public static T GetJsonData<T>(string text) where T : class{ T data = JsonMapper.ToObject<T>(table.ToJson()); return data; }
|
++调用: MyOO myOO = GetJsonData<MyOO>(json);
|
++运行: ++++立钻哥哥:运行解析会报错,因为Json字符串,包含了很多对象和字段,而数据MyOO,MyTestModel,MyTestModel2对象,并没有全部和Json字符串字段一一对应,LitJson解析很严谨; |
++A.7.5.2、使用Newtonsoft.Json(JsonConvert.DeserializeObject
++解析方法 public static T GetJsonData<T>(string text) where T : class{ T data = JsonConvert.DeserializeObject<T>(text); return data; }
|
++调用: MyOO myOO = GetJsonData<MyOO>(json);
|
++运行: ++++立钻哥哥:运行不会报错,完全解析; |
++A.7.5.3、使用Unity自带JsonUtility(JsonUtility.FromJson
++解析方法: public static T GetJsonData<T>(string text) where T : class{ T data = JsonUtility.FromJson<T>(text); return data; }
|
++调用: MyOO myOO = GetJsonData<MyOO>(json);
|
++运行: ++++立钻哥哥:有的对象解析不出,会报错; |
###A.7.6、Unity的Json解析(读取Json文件) |
++A.7.6、Unity的Json解析(读取Json文件)
++++立钻哥哥:在Unity中,自带的JsonUtility中的5个接口:FromJson
++++一个好用的JSON在线编辑:http://www.kjson.com/jsoneditor/?f=1
namespace UnityEngine{ public static class JsonUtility{ //Static Methods public static T FromJson<T>(string json);
[ThreadAndSerializationSafe] [MethodImpl(MethodImplOptions.InternalCall)] public static extern object FromJson(string json, Type type);
[ThreadAndSerializationSafe] [MethodImpl(MethodImplOptions.InternalCall)] public static extern void FromJsonOverwrite(string json, object objectToOverwrite);
public static string ToJson(object obj);
[ThreadAndSerializationSafe] [MethodImpl(MethodImplOptions.InternalCall)] public static extern string ToJson(object obj, bool prettyPrint);
} //立钻哥哥:public static class JsonUtility } //立钻哥哥:namespace UnityEngine{} |
++Json解析(读取Json文件)
++1、首先准备一个Json文件 {“gameName”:”立钻哥哥Json测试”, “version”:”1.0”, “isStereo”:”false”, “isUseHardWare”:”true”, “statusList”:[{“name”:”test”, “id”:”yanlz2018”}]}
|
++2、创建对象类(用来存放从Json文本中读取的内容) using UnityEngine; using System; using System.Collections;
[Serializable] public class MyGameStatus{ public string gameName; public string version; public bool isStereo; public bool isUseHardWare; public MyReferences[] statusList; } //立钻哥哥:public class GameStatus{}
[Serializable] public class MyReferences{ public string name; public int id; } //立钻哥哥:public class MyReferences{}
|
++3、需要一个读取类 using UnityEngine; using System.Collections; using System.IO; using System.Runtime.Serialization.Formatters.Binary;
public class MyLoadJson : MonoBehaviour{ public static MyGameStatus LoadJsonFromFile(){ BinaryFormatter bf = new BinaryFormatter();
string jsonPath = Application.dataPath + “/Resources/MyJonsTest.json”; if(!File.Exists(jsonPath)){ return null; }
StreamReader sr = new StreamReader(jsonPath); if(sr == null){ return null; }
string json = sr.ReadToEnd(); if(json.Length > 0){ return JsonUtility.FromJson<MyGameStatus>(json); }
return null; } //立钻哥哥:public static MyGameStatus LoadJsonFromFile(){}
} //立钻哥哥:public class MyLoadJson:MonoBehaviour{}
++========================================== ++利用Deserialize():解析Json为二进制格式,然后在反序列化为字符串,可能是编码格式问题,不能正确反序列化,可能报错!?(所以使用了以上的StreamReader来处理) FileStream file = File.Open(jsonPath); if(file.Length == 0){ return null; }
string json = (string)bf.Deserialize(file); file.Close();
|
++4、调用(在Update中,使用L键来加载Json文件) using UnityEngine; using System.Collections; using System; using System.Runtime.Serialization.Formatters.Binary; using System.IO;
public class MyReadJson : MonoBehaviour{ void Update(){ if(Input.GetKeyDown(KeyCode.S)){ //DoMySave(); }
if(Input.GetKeyDown(KeyCode.L)){ MyGameStatus status = MyLoadJson.LoadJsonFromFile(); Debug.Log(status); } } } //立钻哥哥:public class MyReadJson:MonoBehaviour{}
|
++5、运行测试 ++++立钻哥哥:在场景中,建立一个空对象,然后把MyReadJson拖拽到对象上,运行,按下L键,就可以使用断点查看,也可以看Log输出;
|
++6、写Json文件
++++立钻哥哥:使用BinaryFormatter来处理,保存的Json文本会有空格,NULL和乱码,这个主要是编码格式的问题,所以,我们使用File.WriteAllText()来处理;
public void DoMySave(){ string json = JsonUtility.ToJson(gameStatus); string savePath = Application.dataPath + “/Resources/MyJsonTest.json”; File.WriteAllText(savePath, json, Encoding.UTF8);
Debug.Log(“立钻哥哥:save:===>” + savePath); } |
using UnityEngine; using System.Collections; using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Text;
public class MyWriteJson : MonoBehaviour{ public MyGameStatus gameStatus; public GameObject[] objects;
void Start(){ gameStatus = new MyGameStatus(); gameStatus.statusList = new MyReferences[objects.Length]; gameStatus.gameName = “立钻哥哥Json测试”;
for(int i = 0; i < objects.Length; i++){ gameStatus.statusList[i] = new MyReferences(); gameStatus.statusList[i].id = i; gameStatus.statusList[i].name = object[i].name; } }
public void DoMySave(){ string json = JsonUtility.ToJson(gameStatus); string savePath = Application.dataPath + “/Resources/MyJsonTest.json”; File.WriteAllText(savePath, json, Encoding.UTF8);
Debug.Log(“立钻哥哥:save:===>” + savePath); }
} //立钻哥哥:public class WriteJson:MonoBehaviour{} |
++调试运行: ++++立钻哥哥:在MyWriteJson的属性面板上,给objects拖拽几个cube,作为保存到Json文件中的内容的一部分,然后运行Unity,按下“S”保存键,就会在当前工程下的/Asset/Resources/下生成一个MyJsonTest.json的文件; ++++Json内容:{“gameName”:”立钻哥哥Json测试”, “version”:””, “isStereo”:true, “isUserHardWare”:false, “statusList”:[{“name”:”Cube01”, “id”:0}, {“name”:”Cube02”, “id”:1}]} |
###A.7.7、Unity解析Json字符串 |
++A.7.7、Unity解析Json字符串(LitJson.dll)
++++立钻哥哥:将LitJson.dll文件拖到Unity工程中(在Unity中的脚本开头引入:using LitJson;);
++++引入LitJson.dll后,可以在脚本中将一个对象转化为Json字符串,或将Json字符串转为Json对象;
++++在使用LitJson时,建议使用JsonData, JsonMapper来处理Json的编码和解析;
++++在Json中{}花括号表示一个对象;[]中括号表示一个数组;
++A.7.7.1、用JsonData类以及ToJson()方法输出一个Json字符串(new JsonData())
{“name”:”立钻哥哥”, “friend”:”小珏妹妹”, “sex”:”male”}
JsonData myData = new JsonData(); myData[“name”] = “立钻哥哥”; myData[“friend”] = “小珏妹妹”; myData[“sex”] = “male”;
string myJson = myData.ToJson(); print(myJson); |
++A.7.7.2、对象中嵌套对象(new JsonData())
{“name”:”立钻哥哥”, “like”:”study”, “sister”:{“name”:”亦菲妹妹”, “like”:”run”}}
void Start(){ JsonData myData = new JsonData(); myData[“name”] = “立钻哥哥”; myData[“like”] = “study”; myData[“sister”] = new JsonData(); myData[“sister”][“name”] = “亦菲妹妹”; myData[“sister”][“like”] = “run”;
string myJson = myData.ToJson(); print(myJson); } |
++A.7.7.3、读取Json字符串(JsonMapper.ToObject())
void Start(){ JsonData myData = JsonMapper.ToObject(“{‘name’:’立钻哥哥’, ‘friend’:’小珏妹妹’, ‘sex’:’male’}”); print(myData[“name”]); } ++输出:立钻哥哥 |
JsonData myData = JsonMapper.ToObject(“{‘name’=’立钻哥哥’, ‘like’:’study’, ‘sister’:{‘name’:’亦菲妹妹’, ‘like’:’run’}}”); print(myData[“sister”][“name”] + “ : ” + myData[“sister”][“like”]); ++输出:亦菲妹妹 : run |
++A.7.7.4、将对象转Json字符串(JsonMapper.ToJson())
void Start(){ MyPlayer myPlayer = new MyPlayer(); myPlayer.name = “立钻哥哥”; myPlayer.age = 28;
string myJson = JsonMapper.ToJson(myPlayer); print(myJson); } ++打印结果:{“name”:”立钻哥哥”, “age”:28} |
++A.7.7.5、将对象数组转Json字符串(JsonMapper.ToJson())
class MyPlayer{ public string name; public int age;
public MyPlayer(string name, int age){ this.name = name; this.age = age } } //立钻哥哥:class MyPlayer{}
void Start(){ MyPlayer myPlayer01 = new MyPlayer(“立钻哥哥”, 28); MyPlayer myPlayer02 = new MyPlayer(“小珏妹妹”, 18); MyPlayer myPlayer03 = new MyPlayer(“亦菲妹妹”, 20); MyPlayer[] playerArr = { myPlayer01, myPlayer02, myPlayer03};
print(JsonMapper.ToJson(playerArr)); } ++打印结果:[{“name”:”立钻哥哥”, “age”:28}, {“name”:”小珏妹妹”, “age”:25}, {“name”:”亦菲妹妹”, “age”:20}] |
++A.7.7.6、读取Json字符串(JsonMapper.ToObject())
void Start(){ string myJson = “{‘name’:’立钻哥哥’, ‘age’:’28’, ‘friend’:[‘小珏妹妹’, ‘18’, ‘run’]}”; JsonData myData = JsonMapper.ToObject(myJson);
print(myData[“name”]); //输出:立钻哥哥 print(myData[“age”]); //输出:28 print(myData[“friend”][0]); //输出:小珏妹妹 print(myData[“friend”][1]); //输出:18 print(myData[“friend”][2]); //输出:run } |
++A.7.7.7、利用程序输出JSON字符串(JsonMapper.ToJson())
public class MyPlayer{ public string name; public string age; public MyFriend friend; } //立钻哥哥:public class MyPlayer{}
public class MyFriend{ public string name; public stirng age; public string[] friends; } //立钻哥哥:public class MyFriend{}
void Start(){ MyFriend myFriend = new MyFriend(); myFriend.name = “小珏妹妹”; myFriend.age = “18”; myFriend.friends = new string[3]; myFriend.friends[0] = “Jue01”; myFriend.friends[1] = “Jue02”; myFriend.friends[2] = “Jue03”;
MyPlayer myPlayer = new MyPlayer(); myPlayer.name = “立钻哥哥”; myPlayer.age = “28”; myPlayer.friend = myFriend;
print(JsonMapper.ToJson(myPlayer)); }
|
++输出:{“name”:”立钻哥哥”, “age”:”28”, “friend”:{“name”:”小珏妹妹”, “age”:”18”, “friends”:[“Jue01”, “Jue02”, “Jue03”]}} |
++A.7.7.8、读取Json字符串(JsonMapper.ToObject<>())
public class MyPlayer{ public string name; public string age; public MyFriend friend; } //立钻哥哥:public class MyPlayer{}
public class MyFriend{ public string name; public stirng age; public string[] friends; } //立钻哥哥:public class MyFriend{}
void Start(){ string myJson = “{‘name’:’立钻哥哥’, ‘age’:’28’, ‘friend’:{‘name’:’小珏妹妹’, ‘age’:’18’, ‘friends’:[‘Jue01’, ‘Jue02’, ‘Jue03’]}}”; MyPlayer myPlayer = JsonMapper.ToObject<MyPlayer>(myJson);
print(myPlayer.friend.friends[0]); //输出:Jue01 } |
++A.7.7.9、组拼JSON字符串(new JsonData())
void Start(){ JsonData myData = new JsonData(); myData[“name”] = “立钻哥哥”; myData[“age”] = “28”; myData[“friend”] = new JsonData(); myData[“friend”][“name”] = “小珏妹妹”; myData[“friend”][“age”] = “18”; myData[“friend”][“friends”] = new JsonData{“Jue01”, “Jue02”, “Jue03”};
print(myData.ToJson()); } ++输出:{“name”:”立钻哥哥”, “age”:”28”, “friend”:{“name”:”小珏妹妹”, “age”:”18”, “friends”:[“Jue01”, “Jue02”, “Jue03”]}} |
#第二篇:中级进阶篇 |
++立钻哥哥推荐的拓展学习链接(Link_Url):
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
++++JSON数据结构:https://blog.csdn.net/VRunSoftYanlz/article/details/82026644
++++HTC_VIVE开发基础:https://blog.csdn.net/VRunSoftYanlz/article/details/81989970
++++Unity5.x用户手册:https://blog.csdn.net/VRunSoftYanlz/article/details/81712741
++++Unity面试题ABC:https://blog.csdn.net/vrunsoftyanlz/article/details/78630687
++++Unity面试题D:https://blog.csdn.net/VRunSoftYanlz/article/details/78630838
++++Unity面试题E:https://blog.csdn.net/vrunsoftyanlz/article/details/78630913
++++Unity面试题F:https://blog.csdn.net/VRunSoftYanlz/article/details/78630945
++++Cocos2dx面试题:https://blog.csdn.net/VRunSoftYanlz/article/details/78630967
++++Lua快速入门篇(Xlua拓展):https://blog.csdn.net/VRunSoftYanlz/article/details/81173818
++++Lua快速入门篇(XLua教程):https://blog.csdn.net/VRunSoftYanlz/article/details/81141502
++++Lua快速入门篇(基础概述):https://blog.csdn.net/VRunSoftYanlz/article/details/81041359
++++框架知识点:https://blog.csdn.net/VRunSoftYanlz/article/details/80862879
++++游戏框架(UI框架夯实篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80781140
++++游戏框架(初探篇):https://blog.csdn.net/VRunSoftYanlz/article/details/80630325
++++设计模式简单整理:https://blog.csdn.net/vrunsoftyanlz/article/details/79839641
++++专题:设计模式(精华篇):https://blog.csdn.net/VRunSoftYanlz/article/details/81322678
++++U3D小项目参考:https://blog.csdn.net/vrunsoftyanlz/article/details/80141811
++++UML类图:https://blog.csdn.net/vrunsoftyanlz/article/details/80289461
++++Unity知识点0001:https://blog.csdn.net/vrunsoftyanlz/article/details/80302012
++++Unity知识点0008:https://blog.csdn.net/VRunSoftYanlz/article/details/81153606
++++U3D_Shader编程(第一篇:快速入门篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372071
++++U3D_Shader编程(第二篇:基础夯实篇):https://blog.csdn.net/vrunsoftyanlz/article/details/80372628
++++Unity引擎基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78881685
++++Unity面向组件开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78881752
++++Unity物理系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78881879
++++Unity2D平台开发:https://blog.csdn.net/vrunsoftyanlz/article/details/78882034
++++UGUI基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78884693
++++UGUI进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78884882
++++UGUI综合:https://blog.csdn.net/vrunsoftyanlz/article/details/78885013
++++Unity动画系统基础:https://blog.csdn.net/vrunsoftyanlz/article/details/78886068
++++Unity动画系统进阶:https://blog.csdn.net/vrunsoftyanlz/article/details/78886198
++++Navigation导航系统:https://blog.csdn.net/vrunsoftyanlz/article/details/78886281
++++Unity特效渲染:https://blog.csdn.net/vrunsoftyanlz/article/details/78886403
++++Unity数据存储:https://blog.csdn.net/vrunsoftyanlz/article/details/79251273
++++Unity中Sqlite数据库:https://blog.csdn.net/vrunsoftyanlz/article/details/79254162
++++WWW类和协程:https://blog.csdn.net/vrunsoftyanlz/article/details/79254559
++++Unity网络:https://blog.csdn.net/vrunsoftyanlz/article/details/79254902
++++C#事件:https://blog.csdn.net/vrunsoftyanlz/article/details/78631267
++++C#委托:https://blog.csdn.net/vrunsoftyanlz/article/details/78631183
++++C#集合:https://blog.csdn.net/vrunsoftyanlz/article/details/78631175
++++C#泛型:https://blog.csdn.net/vrunsoftyanlz/article/details/78631141
++++C#接口:https://blog.csdn.net/vrunsoftyanlz/article/details/78631122
++++C#静态类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630979
++++C#中System.String类:https://blog.csdn.net/vrunsoftyanlz/article/details/78630945
++++C#数据类型:https://blog.csdn.net/vrunsoftyanlz/article/details/78630913
++++Unity3D默认的快捷键:https://blog.csdn.net/vrunsoftyanlz/article/details/78630838
++++游戏相关缩写:https://blog.csdn.net/vrunsoftyanlz/article/details/78630687
++++UnityAPI.Rigidbody刚体:https://blog.csdn.net/VRunSoftYanlz/article/details/81784053
++++UnityAPI.Material材质:https://blog.csdn.net/VRunSoftYanlz/article/details/81814303
++++UnityAPI.Android安卓:https://blog.csdn.net/VRunSoftYanlz/article/details/81843193
++++UnityAPI.AndroidJNI安卓JNI:https://blog.csdn.net/VRunSoftYanlz/article/details/81879345
++++UnityAPI.Transform变换:https://blog.csdn.net/VRunSoftYanlz/article/details/81916293
++++立钻哥哥Unity 学习空间: http://blog.csdn.net/VRunSoftYanlz/
--_--VRunSoft:lovezuanzuan--_--