|
由于某些原因需要将数据保存在本地,并且在某些时候进行编辑并加载,比如保存场景信息,保存游戏状态,保存运行时获得的数据等。
常规的方法有XML,二进制和JSON,前两个不需要通过第三方库实现,缺点是相对繁琐。JSON的好处是数据轻量,过程简单,这次遇到数据保存的需求时,尝试了这三种方法,最终选择了JSON。
导入JSON库
这里使用的是同事推荐的JSON.cs,下载地址。
代码中添加命名空间
using MiniJSON2;
JSON库的使用
public JSON(object jsonKey , object jsonValue)
{
fields.Add(jsonKey.ToString(),jsonValue);
}
JSON数据库的一个关键API是JSON(object Key ,object Value),它类似Dictionary<key,value>类型,使用方法是将Value与某一个key一一对应。
导出JSON到文件
为了换装,使用的数据结构是Dictionary<string name, Dictionary<int currentNum, string path>>,从效果上来说就是希望通过换装部位名称加一个数字,就能得到应有资源的地址,从而用Resources.Load或者www来加载资源。接下来就是思考如何将他们转成JSON数据,开始还想着既然有三个变量,那我应该用三个数据来保存以便以后加载时组合吧,但……嗯想想也是挺傻的,估计是最近感冒了(一定是这样 (▽`) )。
private void SetJsonData(ref JSON resJson, string key)
{
List<string> res_man = new List<string>();
if (avatarData._avatarResData.ContainsKey(key)) //判断key是否存在
{
foreach (KeyValuePair<int, strin> i in avatarData._avatarResData[key])
{
res_man.Add(i.Value);
}
resJson[key] = res_man.ToArray();
}
else
Debug.Log(key + &#34;key is none&#34;);
Debug.Log(key + &#34; is done=================&#34;);
}
这里的avatarData._avatarResData[key]就是之前定义的字典数据,通过遍历avatarData._avatarResData这个字典数据,得到某个key的所有路径数组数据并保存在临时变量res_man里,之后通过resJson[key] = res_man.ToArray();将res_man里的数据赋值给resJson[key],这样得到的JSON数据里即有了[key]也有了与之对应的[value](数组型value)。接下来需要将处理好的JSON数据保存到本地。
首先需要添加文件处理的命名空间,
using System.IO;
然后添加将JSON数据保存到本地的方法:
void SaveJsonToFile(JSON json)
{
File.WriteAllText(Application.dataPath + &#34;/Resources/_avatarResDataForMobile.json&#34;,
json.serialized,
System.Text.Encoding.UTF8);
}
这里用到JSON.serialized方法,其目的是将JSON数据序列化,进而使用Encoding.UTF8的方式保存数据。保存的格式可以是txt或者json。
读取JSON文件
首先添加获取本地文件的方法,因为之前我将文件保存在Resources文件夹下,因此获取地址也是写死的(不建议)。
void LoadJsonFromFile(ref JSON json)
{
TextAsset txt = Resources.Load(&#34;_avatarResDataForMobile&#34;) as TextAsset;
json.serialized = txt.text;
}
然后创建LoadAvatarData()进行调用。
public void LoadAvatarData()
{
JSON resJson = new JSON();
LoadJsonFromFile(ref resJson);
}
经过以上两步操作,获取的JSON数据就被保存在resJson之中。
使用JSON接口还原数据
以上已经获取到JSON数据,再将数据还原也不难,直接上代码。
public void LoadAvatarData()
{
JSON resJson = new JSON();
LoadJsonFromFile(ref resJson);
GetJsonData(ref resJson, &#34;tshirt&#34;);//将JSON数据还原成源数据
}
private void GetJsonData(ref JSON resJson,string key)
{
string[] res_man = resJson.ToArray<string>(key);
int t = 0;
if (!AvatarResourceData._avatarResDataForMobile.ContainsKey(key)) //判断key是否存在
AvatarResourceData._avatarResDataForMobile.Add(key, new Dictionary<int, string>());
foreach (string s in res_man)
{
t++;
AvatarResourceData._avatarResDataForMobile[key].Add(t, s);
}
}
这里需要注意的是AvatarResourceData._avatarResDataForMobile这个变量是我在其他地方定义的全局变量,类型和上文提到的_avatarResData一样,由于某些原因需要这样(懒)。
public Dictionary<string, Dictionary<int, string>> _avatarResData = new Dictionary<string, Dictionary<int, string>>();
public static Dictionary<string, Dictionary<int, string>> _avatarResDataForMobile = new Dictionary<string, Dictionary<int, string>>();总结
使用JSON库的关键是
JSON(object Key ,object Value)
这可以定义任意类型key与任意类型value的绑定,实现各种格式的保存及加载。
附完整代码,供参考(由于文章需要,上文中的部分代码做了简化,以便理解)。对了,这里还有种数据保存方式:PlayerPrefs.SetString(string key, string value),和字典类型类似,可以将value保存在本地某处,缺点是这个路径安卓端获取不到,因此作罢。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MiniJSON2;
using System.IO;
public class ReadWriteAvatarRes : MonoBehaviour {
public AvatarResourceData avatarData;
private void Start()
{
if (Resources.Load(&#34;_avatarResDataForMobile&#34;) == null)
SaveAvatarData();
LoadAvatarData();
}
public void SaveAvatarData()
{
JSON resJson = new JSON();
SetJsonData(ref resJson, &#34;tshirt&#34;);
SetJsonData(ref resJson, &#34;hair&#34;);
SetJsonData(ref resJson, &#34;hat&#34;);
SetJsonData(ref resJson, &#34;pants&#34;);
SetJsonData(ref resJson, &#34;shoes&#34;);
SetJsonData(ref resJson, &#34;glasses&#34;);
SetJsonData(ref resJson, &#34;headset&#34;);
SetJsonData(ref resJson, &#34;mask&#34;);
SetJsonData(ref resJson, &#34;jacket&#34;);
SetJsonData(ref resJson, &#34;face&#34;);
SetJsonData(ref resJson, &#34;eyebow&#34;);
SetJsonData(ref resJson, &#34;lip&#34;);
SetJsonData(ref resJson, &#34;eye&#34;);
//PlayerPrefs.SetString(&#34;_avatarResDataForMobile&#34;, resJson.serialized);
SaveJsonToFile(resJson);
}
private void SetJsonData(ref JSON resJson, string key)
{
List<string> res_man = new List<string>();
List<string> res_girl = new List<string>();
if (avatarData._avatarResData.ContainsKey(&#34;G_&#34; + key)) //判断key是否存在
{
foreach (KeyValuePair<int, string> i in avatarData._avatarResData[&#34;G_&#34; + key])
{
res_girl.Add(i.Value);
}
resJson[&#34;G_&#34; + key] = res_girl.ToArray();
}
else
Debug.Log(key + &#34;type is none G_&#34;);
if(avatarData._avatarResData.ContainsKey(&#34;M_&#34; + key))
{
foreach (KeyValuePair<int, string> i in avatarData._avatarResData[&#34;M_&#34; + key])
{
res_man.Add(i.Value);
}
resJson[&#34;M_&#34; + key] = res_man.ToArray();
}
else
Debug.Log(key + &#34;type is none&#34;);
Debug.Log(key + &#34; is done=================&#34;);
}
public void LoadAvatarData()
{
JSON resJson = new JSON();
//resJson.serialized = PlayerPrefs.GetString(&#34;_avatarResDataForMobile&#34;);
LoadJsonFromFile(ref resJson);
GetJsonData(ref resJson, &#34;tshirt&#34;);
GetJsonData(ref resJson, &#34;hair&#34;);
GetJsonData(ref resJson, &#34;hat&#34;);
GetJsonData(ref resJson, &#34;pants&#34;);
GetJsonData(ref resJson, &#34;shoes&#34;);
GetJsonData(ref resJson, &#34;glasses&#34;);
GetJsonData(ref resJson, &#34;headset&#34;);
GetJsonData(ref resJson, &#34;jacket&#34;);
GetJsonData(ref resJson, &#34;mask&#34;);
GetJsonData(ref resJson, &#34;face&#34;);
GetJsonData(ref resJson, &#34;eyebow&#34;);
GetJsonData(ref resJson, &#34;lip&#34;);
GetJsonData(ref resJson, &#34;eye&#34;);
}
private void GetJsonData(ref JSON resJson,string key)
{
string[] res_girl = resJson.ToArray<string>(&#34;G_&#34; + key);
string[] res_man = resJson.ToArray<string>(&#34;M_&#34; + key);
int i = 0;
int t = 0;
if (!AvatarResourceData._avatarResDataForMobile.ContainsKey(&#34;G_&#34;+ key))
AvatarResourceData._avatarResDataForMobile.Add(&#34;G_&#34;+ key, new Dictionary<int, string>());
if (!AvatarResourceData._avatarResDataForMobile.ContainsKey(&#34;M_&#34; + key))
AvatarResourceData._avatarResDataForMobile.Add(&#34;M_&#34; + key, new Dictionary<int, string>());
foreach (string s in res_girl)
{
i++;
AvatarResourceData._avatarResDataForMobile[&#34;G_&#34; + key].Add(i, s);
}
foreach (string s in res_man)
{
t++;
AvatarResourceData._avatarResDataForMobile[&#34;M_&#34; + key].Add(t, s);
}
}
void LoadJsonFromFile(ref JSON json)
{
TextAsset txt = Resources.Load(&#34;_avatarResDataForMobile&#34;) as TextAsset;
json.serialized = txt.text;
}
void SaveJsonToFile(JSON json)
{
File.WriteAllText(Application.dataPath + &#34;/Resources/_avatarResDataForMobile.json&#34;, json.serialized, System.Text.Encoding.UTF8);
} |
|