Unity中常用的序列化方式有三种,二进制序列化,xml,json
二进制序列化因为不能维护字段,通常用于图片,音频,视频等文件的传输
Xml相比Json有阅读直白的优势,通常用于配置表
Json效率比Xml高,常用于网络传输

Unity还提供了PlayerPrefs类进行数据持久化,只适用于一些小游戏.

Xml序列化与反序列化

代码

using System;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;public class SerializeTool {/// <summary>/// xml序列化/// </summary>/// <param name="path"></param>/// <param name="obj"></param>public static void XmlSerialize(string path, object obj) {try{if (File.Exists(path)){File.Delete(path);//已经存在同名文件就删除}//创建新的文件 using语法可以在范围结束后自动调用Dispose方法using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)){//设置utf8编码 防止乱码using (StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.UTF8)){XmlSerializer xs = new XmlSerializer(obj.GetType());xs.Serialize(sw, obj);//序列化}}}catch (Exception e){Debug.Log(path + ":" + e);}}/// <summary>/// xml反序列化/// </summary>/// <typeparam name="T"></typeparam>/// <param name="path"></param>/// <returns></returns>public static T XmlDeserialize<T>(string path) where T :class {T t = default(T);try{//using语法可以在范围结束后自动调用Dispose方法using (FileStream fs = new FileStream(path,FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite)){//反序列化XmlSerializer xs = new XmlSerializer(typeof(T));t = (T)xs.Deserialize(fs);//fs.Dispose();}}catch (Exception e){Debug.Log(path + ":" + e);}return t;}
}

调用一下代码生成xml文件测试,觉得exsl给策划,然后转回xml作为物品道具之类的属性表,非常合适.

<?xml version="1.0" encoding="ISO-8859-1"?>
<StarData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<position>
<x>104.39492</x>
<y>110.7</y>
<z>101.098129</z>
</position>
<rotation>
<x>0</x>
<y>0</y>
<z>0</z>
<w>1</w>
<eulerAngles>
<x>-0</x>
<y>0</y>
<z>0</z>
</eulerAngles>
</rotation>
<entityName>Star(Clone)147</entityName>
<speedX>22.6322365</speedX>
<speedY>-5.658059</speedY>
<speedZ>-56.58059</speedZ>
<lowestHeight>35</lowestHeight>
<duration>2</duration>
</StarData>

xml标签

此外xml有一些标签可供选择,会对生成的xml格式有一些影响
[XmlElement(“testString”)]//设置属性名字
[XmlAttribute(“testString”)]//设置该属性为特性
[XmlType(“testString”)]//打在类名前,设置类的名字
[XmlArray(elementName: “testString”)]//设置列表名
[XmlArrayItem(elementName: “testString”)]//设置列表中的元素名
[XmlIgnore]//忽略该字段

Json

目前比较流行的,效率高的json框架是litjson.
litjson如果想使用自动序列化/解析时,有几个需要注意的地方
1.它不支持float类型数据
2.字典第一个数据类型必须为string
3.类与js串上的字段必须完全一致,导致了无法更新字段

不过我们可以为每一个类编写序列化/反序列化方法,缺点是工作量有点大.
介于以上种种原因,我们使用litjson为每一个类编写序列化和反序列化方法

代码

我们将json序列化和反序列化的方法封装成下面的格式.
注意不要这样打log,因为sr.ReadToEnd()中的值只能读取一次,下一次sb中就空值了

Debug.Log(sr.ReadToEnd());
StringBuilder sb = new StringBuilder(sr.ReadToEnd());//读取全部数据
/// <summary>
/// json序列化到本地
/// </summary>
/// <param name="path"></param>
/// <param name="json"></param>
public static void JsonSerialize(string path, string json)
{try{if (File.Exists(path)){File.Delete(path);//已经存在同名文件就删除}//创建新的文件 using语法可以在范围结束后自动调用Dispose方法using (FileStream fs = new FileStream(path, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite)){//设置utf8编码 防止乱码using (StreamWriter sw = new StreamWriter(fs, Encoding.UTF8)){sw.WriteLine(json);}}}catch (Exception e){Debug.Log(path + ":" + e);}
}
/// <summary>
/// 读取json文件
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static JsonData JsonDeserialize(string path)
{try{//using语法可以在范围结束后自动调用Dispose方法using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite)){using (StreamReader sr = new StreamReader(fs, Encoding.UTF8)){StringBuilder sb = new StringBuilder(sr.ReadToEnd());//读取全部数据JsonData jsonData = JsonMapper.ToObject(sb.ToString());//获取jsonDatareturn jsonData;}}}catch (Exception e){Debug.Log(path + ":" + e);}return null;
}

我们在基类中定义两个方法,一个用于获取完整的json序列化,一个用于续写序列化方法
再定义一个反序列化的方法

public abstract class BaseData {public Vector3 position;//物体的位置public Quaternion rotation;//物体的旋转public string entityName;//实体的名字/// <summary>/// 获取序列化js串/// </summary>/// <returns></returns>public string GetJson() {StringBuilder sb = new StringBuilder();JsonWriter jw = new JsonWriter(sb);jw.WriteObjectStart();//开始写入ToJson(jw);jw.WriteObjectEnd();//结束写入return sb.ToString();}/// <summary>/// 序列化方法 可续写/// </summary>/// <param name="jw"></param>public virtual void ToJson(JsonWriter jw) {if (jw==null){throw new Exception("null");}jw.WritePropertyName("position");//写入第一个属性jw.WriteObjectStart();//开始写入集合jw.WritePropertyName("x");jw.Write(position.x);jw.WritePropertyName("y");jw.Write(position.y);jw.WritePropertyName("z");jw.Write(position.z);jw.WriteObjectEnd();//结束写入集合jw.WritePropertyName("rotation");jw.WriteObjectStart();//开始写入集合jw.WritePropertyName("w");jw.Write(rotation.w);jw.WritePropertyName("x");jw.Write(rotation.x);jw.WritePropertyName("y");jw.Write(rotation.y);jw.WritePropertyName("z");jw.Write(rotation.z);jw.WriteObjectEnd();//结束写入集合jw.WritePropertyName("entityName");jw.Write(entityName);}/// <summary>/// 写入json数据/// </summary>public virtual void SetJsonData(JsonData data){if (data == null){throw new Exception("null");}JsonData positionJson = data["position"];position.x = float.Parse(positionJson["x"].ToString());//物体的位置position.y = float.Parse(positionJson["y"].ToString());//物体的位置position.z = float.Parse(positionJson["z"].ToString());//物体的位置JsonData rotationJson = data["rotation"];rotation.w = float.Parse(rotationJson["w"].ToString());rotation.x = float.Parse(rotationJson["x"].ToString());rotation.y = float.Parse(rotationJson["y"].ToString());rotation.z = float.Parse(rotationJson["z"].ToString());entityName = data["entityName"].ToString();//实体的名字}
}

在子类中续写一下序列化和反序列化的方法,规避一下重复敲代码

using LitJson;public class StarData : BaseData {public float speedX;//X轴速度public float speedY;//Y轴速度public float speedZ;//Z轴速度public float lowestHeight;//低于lowestHeight高度后开始拖尾特效public float duration;//持续时间/// <summary>/// 续写序列化方法/// </summary>/// <param name="jw"></param>public override void ToJson(JsonWriter jw){base.ToJson(jw);jw.WritePropertyName("speedX");jw.Write(speedX);jw.WritePropertyName("speedY");jw.Write(speedY);jw.WritePropertyName("speedZ");jw.Write(speedZ);jw.WritePropertyName("lowestHeight");jw.Write(lowestHeight);jw.WritePropertyName("duration");jw.Write(duration);}/// <summary>/// 写入json数据/// </summary>public override void SetJsonData(JsonData data){base.SetJsonData(data);speedX = float.Parse(data["speedX"].ToString());speedY = float.Parse(data["speedY"].ToString());speedZ = float.Parse(data["speedZ"].ToString());lowestHeight = float.Parse(data["lowestHeight"].ToString());duration = float.Parse(data["duration"].ToString());}
}

接下来我们随便构造一个数据类 ,然后调用

SerializeTool.JsonSerialize(Application.streamingAssetsPath + "/star.json", star.data.GetJson());

将序列化的json保存到本地
检查一下数据格式

{"position":{"x":135.904724121094,"y":110.699996948242,"z":49.5925445556641},"rotation":{"w":1.0,"x":0.0,"y":0.0,"z":0.0},"entityName":"Star(Clone)5","speedX":-57.2221565246582,"speedY":-5.72221565246582,"speedZ":22.8888626098633,"lowestHeight":35.0,"duration":2.0}

然后定义一个StarData类型的数据,读取本地刚刚保存的js数据文件,并将json解析保存进这个类中.

data.SetJsonData(SerializeTool.JsonDeserialize(Application.streamingAssetsPath + "/star.json"));

最后从基类和子类选几个属性,简单的测试一下,没有问题

我想,还差个加密,就可以用于单机游戏存档了吧.
这个方法写起来还是比较麻烦的,要手动给所有数据类编写序列化,反序列化方法.但是规避了上面的一些缺点.
如果有更好的实现方法,欢迎指教.

数据持久化Xml与Json相关推荐

  1. 【XML】Java对象数据的XML和JSON表示

    XML与JSON 本文主要是基于之前的一份Java代码,根据合理数据(下面的链接中有),设计对应的XML格式和JSON格式的存储表示,并使用工具对其合法性加以验证. JavaCode 先看Java的代 ...

  2. wp8.1 Study11:APP里文件读写和使用XML和Json序列化

    一.文件读写 1.基本操作(使用FileIO API) 这个方法在上一个stduy已经学过,那么贴出来复习下,代码如下: private async void writeTextToLocalStor ...

  3. 爬虫之scrapy框架的数据持久化存储/保存为scv,json文件

    文章目录 前情回顾 selenium+phantomjs/chrome/firefox execjs模块使用 今日笔记 scrapy框架 小试牛刀 猫眼电影案例 知识点汇总 数据持久化存储(MySQL ...

  4. Unity之数据持久化——Json

    1.Json是什么 JavaScript对象简谱(JavaScript Object Notation) json是国际通用的一种轻量级的数据交换格式,主要在网络通讯中用于传输数据,或本地数据存储和读 ...

  5. 2019尚硅谷大数据Javaweb篇三 Ajax、JSTL、会话技术、过滤器、监听器、xml、json

    2019尚硅谷大数据 Javaweb篇三Ajax.JSTL.会话技术.过滤器.监听器 tags: 大数据 2019尚学堂 categories: Ajax异步请求 JSTL中的if和forEach 会 ...

  6. XML和JSON 数据交换格式

    为什么80%的码农都做不了架构师?>>>    一.什么是数据交换格式? 客户端与服务器常用数据交换格式xml.json.html 二.数据交换格式应用场景 移动端(安卓.IOS)通 ...

  7. php如何返回数据请求数据格式化,PHP以json或xml数据格式返回请求数据的封装代码...

    现在主流的数据格式无非就是json和xml,下面我们来看看如何用php来封装一个返回这两种格式数据的类,下面青岛星网跟大家一起分享. 1.以json格式返回数据 json格式返回数据比较简单,直接将我 ...

  8. XML和JSON两种数据交换格式的比较

    目前,在web开发领域,主要的数据交换格式有XML和JSON,对于XML相信每一个web developer都不会感到陌生: 相比之下,JSON可能对于一些新步入开发领域的新手会感到有些陌生,也可能你 ...

  9. 于数据交换格式XML和JSON的比较

    目前,在web开发领域,主要的数据传输格式有XML和JSON,对于XML相信每一个web developer都不会感到陌生:相比之下,JSON可能对于一些新步入开发领域的新手会感到有些陌生,也可能你之 ...

最新文章

  1. 用LIBSVM做回归和预测的步骤
  2. www.python123.com_Python123
  3. Caused by: java.lang.ClassCastException: weblogic.xml.jaxp.RegistryXMLReader
  4. magento app/design/adminhtml/default/default/template/sales/order/view/info.phtml XSS Vul
  5. 爬虫python下载视频_用python做爬虫下载视频
  6. [Usaco2010 Mar]gather 奶牛大集会
  7. 第14章 任务和特权级保护
  8. RFI to RCE challenge
  9. golang 关闭gc 并手动gc_Golang 防内存泄漏编码原则
  10. MFC---CComboBox控件添加字符串函数InsertString
  11. atitit 技术选型之道. attilax著 艾龙著 1. 标准 2 1.1. 符合趋势度 2 1.2. 简单易用 2 1.3. 文档丰富度 2 1.4. 下载便利性 2 1.5. 性能 2 1.
  12. 计算机设备耗材管理系统,实验室耗材管理方法、系统、计算机设备和存储介质与流程...
  13. 阿尔法贝塔剪枝——中国象棋人机对战
  14. wordcloud绘制词云图的方法
  15. chrome出现Provisional headers are shown
  16. 微信公众平台之模拟登录
  17. 【WordPress】视频有声音无图像
  18. 集群搭建——SGE与PBS
  19. python中def main是什么意思_python main用法解析
  20. python3计算常数e的代码

热门文章

  1. 用浏览器读取图片上的文字信息,这个方法很实用
  2. LDF文件步骤及内容详解
  3. 如何构建和设计高扩展性系统
  4. 『ssh』使用shell远程执行命令
  5. 测试开发技能:java语言之浮点数运算
  6. Laravel引入谷歌验证器
  7. Java面试之异常处理
  8. 小程序中数据的定义和使用
  9. ChatGPT人工智能热潮之下,NCSI功能OCP网卡助力数据中心发展
  10. python做图片美化_如何美化MATLAB和Python画出来的图