Unity3D保存数据到Json(加密、解密)

转载自:http://blog.csdn.net/qinyuanpei/article/details/47775979

Newtonsoft.Json的下载地址:

注意:使用2.0的库http://json.codeplex.com

喜欢我的博客请记住我的名字:秦元培,我的博客地址是:http://qinyuanpei.com 
转载请注明出处,本文作者:秦元培, 本文出处:http://blog.csdn.net/qinyuanpei/article/details/47775979

  大家好,我是秦元培,欢迎大家关注我的博客。近期博客的更新频率基本直降到冰点,因为这段时间实在是忙得没有时间来写博客了。今天想和大家分享的内容是RPG游戏中游戏存档的实现,因为最近在做一个RPG游戏的项目,所以遇到这个问题就随时记录下来,在对知识进行总结的同时可以将这种思路或者想法分享给大家,这是一件快乐而幸运的事情。我讨厌写按部就班的技术教程,因为我觉得学习是一种自我的探索行为,如果一切都告诉你了,探索的过程便会变得没有意义了。

  游戏存档是一种在单机游戏中特别常见的机制,这种机制是你在玩网络游戏的时候无法体验到的,你知道每次玩完一款单机游戏都会把游戏存档保存起来是一种怎样的感觉吗?它就像是一个征战沙场的将军将陪伴自己一生金戈铁马的宝剑静静地收入剑匣,然而每一次打开它的时候都会不由自主的热泪盈眶。人的本性其实就是游戏,我们每一天发生的故事何尝不是一个游戏?有时候让我们怀念的可能并不是游戏本身,而只是搁浅在时光里的那时的我们。好了,游戏存档是我们在游戏世界里雪泥鸿爪,它代表了我们曾经来到过这个世界。以RPG游戏为例,一个一般化的游戏存档应该囊括以下内容:

  • 角色信息:指一切表征虚拟角色成长路线的信息,如生命值、魔法值、经验值等等。
  • 道具信息:指一切表征虚拟道具数量或者作用的信息,如药品、道具、装备等等。
  • 场景信息:指一切和游戏场景相关的信息,如场景名称、角色在当前场景中的位置坐标等等。
  • 事件信息:指一切和游戏事件相关的信息,如主线任务、支线任务、触发性事件等等。

  从以上信息划分的层次来看,我们可以发现在游戏存档中要储存的信息相对是比较复杂的,那么我们这里不得不说说Unity3D中的数据持久化方案PlayerPrefs。该方案采用的是一种键值型的数据存储方案,支持int、string、float三种基本数据类型,通过键名来获取相对应的数值,当值不存在时将返回一个默认值。这种数据存储方案本质上是将数据写入到一个Xml文件。这种方案如果用来存储简单的信息是没有问题的,可是如果用它来存储游戏存档这样负责的数据结构就显得力不从心了。一个更为重要的问题是在数据持久化的过程中我们希望得到是一个结构化的【游戏存档】实例,显然此时松散的PlayerPrefs是不能满足我们的要求的。因此我们想到了将游戏数据序列化的思路,常见的数据序列化思路主要有Xml和JSON两种形式,在使用Xml的数据序列化方案的时候通常有两种思路,即手动建立数据实体和数据字符间的对应关系基于XmlSerializer的数据序列化。其中基于XmlSerializer的数据序列化是利用了[Serializable]这样的语法特性来帮助.NET完成数据实体和数据字符间的对应关系,两种思路本质上一样的。可是我们知道Xml的优点是可读性强,缺点是冗余信息多,因此在权衡了两种方案的利弊后,我决定采用JSON来作为数据序列化的方案,而且JSON在数据实体和数据字符间的对应关系上有着天然的优势,JSON所做的事情不就是将数据实体转化为字符串和从一个字符串中解析出数据实体吗?所以整个方案基本一气呵成。好了,下面我们来看具体的代码实现过程吧!

一、JSON的序列化和反序列化

  这里我使用的是Newtonsoft.Json这个类库,相信大家都是知道的了!因此,序列化和反序列化特别简单。

<code class="language-C# hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 将一个对象序列化为字符串</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><returns></span>The object.<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></returns></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pObject"></span>对象<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pType"></span>对象类型<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> <span class="hljs-title" style="box-sizing: border-box;">SerializeObject</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> pObject)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//序列化后的字符串</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> serializedString = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.Empty;
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用Json.Net进行序列化</span>
        serializedString = JsonConvert.SerializeObject(pObject);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> serializedString;
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 将一个字符串反序列化为对象</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><returns></span>The object.<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></returns></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pString"></span>字符串<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pType"></span>对象类型<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box;">DeserializeObject</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pString,Type pType)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//反序列化后的对象</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> deserializedObject = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用Json.Net进行反序列化</span>
        deserializedObject=JsonConvert.DeserializeObject(pString,pType);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> deserializedObject;
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li></ul>

二、Rijandel加密/解密算法

  因为我们这里要做的是一个游戏存档的方案设计,因为考虑到存档数据的安全性,我们可以考虑采用相关的加密/解密算法来实现对序列化后的明文数据进行加密,这样可以从一定程度上保证游戏存档数据的安全性。因为博主并没有深入地研究过加密/解密方面的内容,所以这里仅仅提供一个从MSDN上获取的Rijandel算法,大家感兴趣的话可以自行去研究。

<code class="language-C# hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> Rijndael加密算法</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pString"></span>待加密的明文<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pKey"></span>密钥,长度可以为:64位(byte[8]),128位(byte[16]),192位(byte[24]),256位(byte[32])<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="iv"></span>iv向量,长度为128(byte[16])<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><returns></span><span class="hljs-xmlDocTag" style="box-sizing: border-box;"></returns></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> <span class="hljs-title" style="box-sizing: border-box;">RijndaelEncrypt</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pString, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pKey)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//密钥</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] keyArray = UTF8Encoding.UTF8.GetBytes(pKey);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//待加密明文数组</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(pString);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Rijndael解密算法</span>
        RijndaelManaged rDel = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateEncryptor();

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回加密后的密文</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, toEncryptArray.Length);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> Convert.ToBase64String(resultArray, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, resultArray.Length);
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> ijndael解密算法</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pString"></span>待解密的密文<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pKey"></span>密钥,长度可以为:64位(byte[8]),128位(byte[16]),192位(byte[24]),256位(byte[32])<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="iv"></span>iv向量,长度为128(byte[16])<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><returns></span><span class="hljs-xmlDocTag" style="box-sizing: border-box;"></returns></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> String <span class="hljs-title" style="box-sizing: border-box;">RijndaelDecrypt</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pString, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pKey)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//解密密钥</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] keyArray = UTF8Encoding.UTF8.GetBytes(pKey);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//待解密密文数组</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] toEncryptArray = Convert.FromBase64String(pString);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Rijndael解密算法</span>
        RijndaelManaged rDel = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateDecryptor();

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回解密后的明文</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, toEncryptArray.Length);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> UTF8Encoding.UTF8.GetString(resultArray);
    }</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li></ul>

三、完整代码

  好了,下面给出完整代码,我们这里提供了两个公开的方法GetData()和SetData()以及IO相关的辅助方法,我们在实际使用的时候只需要关注这些方法就可以了!

<code class="language-C# hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">/**
 * Unity3D数据持久化辅助类
 * 作者:秦元培
 * 时间:2015年8月14日
 **/</span>

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> UnityEngine;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Collections;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.IO;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Text;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Security.Cryptography;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> Newtonsoft.Json;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> IOHelper
{
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 判断文件是否存在</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span> <span class="hljs-title" style="box-sizing: border-box;">IsFileExists</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> fileName)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> File.Exists(fileName);
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 判断文件夹是否存在</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">bool</span> <span class="hljs-title" style="box-sizing: border-box;">IsDirectoryExists</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> fileName)
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> Directory.Exists(fileName);
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 创建一个文本文件    </span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="fileName"></span>文件路径<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="content"></span>文件内容<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">CreateFile</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> fileName,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> content)
    {
        StreamWriter streamWriter = File.CreateText(fileName);
        streamWriter.Write(content);
        streamWriter.Close();
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 创建一个文件夹</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">CreateDirectory</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> fileName)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//文件夹存在则返回</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">if</span>(IsDirectoryExists (fileName))
            <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span>;
        Directory.CreateDirectory(fileName);
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> <span class="hljs-title" style="box-sizing: border-box;">SetData</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> fileName,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> pObject)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//将对象序列化为字符串</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> toSave = SerializeObject(pObject);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//对字符串进行加密,32位加密密钥</span>
        toSave = RijndaelEncrypt(toSave, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"</span>);
        StreamWriter streamWriter = File.CreateText(fileName);
        streamWriter.Write(toSave);
        streamWriter.Close();
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box;">GetData</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> fileName,Type pType)
    {
        StreamReader streamReader = File.OpenText(fileName);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> data = streamReader.ReadToEnd();
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//对数据进行解密,32位解密密钥</span>
        data = RijndaelDecrypt(data, <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"</span>);
        streamReader.Close();
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> DeserializeObject(data,pType);
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> Rijndael加密算法</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pString"></span>待加密的明文<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pKey"></span>密钥,长度可以为:64位(byte[8]),128位(byte[16]),192位(byte[24]),256位(byte[32])<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="iv"></span>iv向量,长度为128(byte[16])<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><returns></span><span class="hljs-xmlDocTag" style="box-sizing: border-box;"></returns></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> <span class="hljs-title" style="box-sizing: border-box;">RijndaelEncrypt</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pString, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pKey)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//密钥</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] keyArray = UTF8Encoding.UTF8.GetBytes(pKey);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//待加密明文数组</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(pString);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Rijndael解密算法</span>
        RijndaelManaged rDel = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateEncryptor();

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回加密后的密文</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, toEncryptArray.Length);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> Convert.ToBase64String(resultArray, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, resultArray.Length);
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> ijndael解密算法</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pString"></span>待解密的密文<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pKey"></span>密钥,长度可以为:64位(byte[8]),128位(byte[16]),192位(byte[24]),256位(byte[32])<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="iv"></span>iv向量,长度为128(byte[16])<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><returns></span><span class="hljs-xmlDocTag" style="box-sizing: border-box;"></returns></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> String <span class="hljs-title" style="box-sizing: border-box;">RijndaelDecrypt</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pString, <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pKey)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//解密密钥</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] keyArray = UTF8Encoding.UTF8.GetBytes(pKey);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//待解密密文数组</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] toEncryptArray = Convert.FromBase64String(pString);

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//Rijndael解密算法</span>
        RijndaelManaged rDel = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> RijndaelManaged();
        rDel.Key = keyArray;
        rDel.Mode = CipherMode.ECB;
        rDel.Padding = PaddingMode.PKCS7;
        ICryptoTransform cTransform = rDel.CreateDecryptor();

        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//返回解密后的明文</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">byte</span>[] resultArray = cTransform.TransformFinalBlock(toEncryptArray, <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">0</span>, toEncryptArray.Length);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> UTF8Encoding.UTF8.GetString(resultArray);
    }


    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 将一个对象序列化为字符串</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><returns></span>The object.<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></returns></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pObject"></span>对象<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pType"></span>对象类型<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> <span class="hljs-title" style="box-sizing: border-box;">SerializeObject</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> pObject)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//序列化后的字符串</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> serializedString = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span>.Empty;
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用Json.Net进行序列化</span>
        serializedString = JsonConvert.SerializeObject(pObject);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> serializedString;
    }

    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 将一个字符串反序列化为对象</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><returns></span>The object.<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></returns></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pString"></span>字符串<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><param name="pType"></span>对象类型<span class="hljs-xmlDocTag" style="box-sizing: border-box;"></param></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">private</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">static</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> <span class="hljs-title" style="box-sizing: border-box;">DeserializeObject</span>(<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> pString,Type pType)
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//反序列化后的对象</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">object</span> deserializedObject = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">null</span>;
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//使用Json.Net进行反序列化</span>
        deserializedObject=JsonConvert.DeserializeObject(pString,pType);
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">return</span> deserializedObject;
    }
}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li><li style="box-sizing: border-box; padding: 0px 5px;">46</li><li style="box-sizing: border-box; padding: 0px 5px;">47</li><li style="box-sizing: border-box; padding: 0px 5px;">48</li><li style="box-sizing: border-box; padding: 0px 5px;">49</li><li style="box-sizing: border-box; padding: 0px 5px;">50</li><li style="box-sizing: border-box; padding: 0px 5px;">51</li><li style="box-sizing: border-box; padding: 0px 5px;">52</li><li style="box-sizing: border-box; padding: 0px 5px;">53</li><li style="box-sizing: border-box; padding: 0px 5px;">54</li><li style="box-sizing: border-box; padding: 0px 5px;">55</li><li style="box-sizing: border-box; padding: 0px 5px;">56</li><li style="box-sizing: border-box; padding: 0px 5px;">57</li><li style="box-sizing: border-box; padding: 0px 5px;">58</li><li style="box-sizing: border-box; padding: 0px 5px;">59</li><li style="box-sizing: border-box; padding: 0px 5px;">60</li><li style="box-sizing: border-box; padding: 0px 5px;">61</li><li style="box-sizing: border-box; padding: 0px 5px;">62</li><li style="box-sizing: border-box; padding: 0px 5px;">63</li><li style="box-sizing: border-box; padding: 0px 5px;">64</li><li style="box-sizing: border-box; padding: 0px 5px;">65</li><li style="box-sizing: border-box; padding: 0px 5px;">66</li><li style="box-sizing: border-box; padding: 0px 5px;">67</li><li style="box-sizing: border-box; padding: 0px 5px;">68</li><li style="box-sizing: border-box; padding: 0px 5px;">69</li><li style="box-sizing: border-box; padding: 0px 5px;">70</li><li style="box-sizing: border-box; padding: 0px 5px;">71</li><li style="box-sizing: border-box; padding: 0px 5px;">72</li><li style="box-sizing: border-box; padding: 0px 5px;">73</li><li style="box-sizing: border-box; padding: 0px 5px;">74</li><li style="box-sizing: border-box; padding: 0px 5px;">75</li><li style="box-sizing: border-box; padding: 0px 5px;">76</li><li style="box-sizing: border-box; padding: 0px 5px;">77</li><li style="box-sizing: border-box; padding: 0px 5px;">78</li><li style="box-sizing: border-box; padding: 0px 5px;">79</li><li style="box-sizing: border-box; padding: 0px 5px;">80</li><li style="box-sizing: border-box; padding: 0px 5px;">81</li><li style="box-sizing: border-box; padding: 0px 5px;">82</li><li style="box-sizing: border-box; padding: 0px 5px;">83</li><li style="box-sizing: border-box; padding: 0px 5px;">84</li><li style="box-sizing: border-box; padding: 0px 5px;">85</li><li style="box-sizing: border-box; padding: 0px 5px;">86</li><li style="box-sizing: border-box; padding: 0px 5px;">87</li><li style="box-sizing: border-box; padding: 0px 5px;">88</li><li style="box-sizing: border-box; padding: 0px 5px;">89</li><li style="box-sizing: border-box; padding: 0px 5px;">90</li><li style="box-sizing: border-box; padding: 0px 5px;">91</li><li style="box-sizing: border-box; padding: 0px 5px;">92</li><li style="box-sizing: border-box; padding: 0px 5px;">93</li><li style="box-sizing: border-box; padding: 0px 5px;">94</li><li style="box-sizing: border-box; padding: 0px 5px;">95</li><li style="box-sizing: border-box; padding: 0px 5px;">96</li><li style="box-sizing: border-box; padding: 0px 5px;">97</li><li style="box-sizing: border-box; padding: 0px 5px;">98</li><li style="box-sizing: border-box; padding: 0px 5px;">99</li><li style="box-sizing: border-box; padding: 0px 5px;">100</li><li style="box-sizing: border-box; padding: 0px 5px;">101</li><li style="box-sizing: border-box; padding: 0px 5px;">102</li><li style="box-sizing: border-box; padding: 0px 5px;">103</li><li style="box-sizing: border-box; padding: 0px 5px;">104</li><li style="box-sizing: border-box; padding: 0px 5px;">105</li><li style="box-sizing: border-box; padding: 0px 5px;">106</li><li style="box-sizing: border-box; padding: 0px 5px;">107</li><li style="box-sizing: border-box; padding: 0px 5px;">108</li><li style="box-sizing: border-box; padding: 0px 5px;">109</li><li style="box-sizing: border-box; padding: 0px 5px;">110</li><li style="box-sizing: border-box; padding: 0px 5px;">111</li><li style="box-sizing: border-box; padding: 0px 5px;">112</li><li style="box-sizing: border-box; padding: 0px 5px;">113</li><li style="box-sizing: border-box; padding: 0px 5px;">114</li><li style="box-sizing: border-box; padding: 0px 5px;">115</li><li style="box-sizing: border-box; padding: 0px 5px;">116</li><li style="box-sizing: border-box; padding: 0px 5px;">117</li><li style="box-sizing: border-box; padding: 0px 5px;">118</li><li style="box-sizing: border-box; padding: 0px 5px;">119</li><li style="box-sizing: border-box; padding: 0px 5px;">120</li><li style="box-sizing: border-box; padding: 0px 5px;">121</li><li style="box-sizing: border-box; padding: 0px 5px;">122</li><li style="box-sizing: border-box; padding: 0px 5px;">123</li><li style="box-sizing: border-box; padding: 0px 5px;">124</li><li style="box-sizing: border-box; padding: 0px 5px;">125</li><li style="box-sizing: border-box; padding: 0px 5px;">126</li><li style="box-sizing: border-box; padding: 0px 5px;">127</li><li style="box-sizing: border-box; padding: 0px 5px;">128</li><li style="box-sizing: border-box; padding: 0px 5px;">129</li><li style="box-sizing: border-box; padding: 0px 5px;">130</li><li style="box-sizing: border-box; padding: 0px 5px;">131</li><li style="box-sizing: border-box; padding: 0px 5px;">132</li><li style="box-sizing: border-box; padding: 0px 5px;">133</li><li style="box-sizing: border-box; padding: 0px 5px;">134</li><li style="box-sizing: border-box; padding: 0px 5px;">135</li><li style="box-sizing: border-box; padding: 0px 5px;">136</li><li style="box-sizing: border-box; padding: 0px 5px;">137</li><li style="box-sizing: border-box; padding: 0px 5px;">138</li><li style="box-sizing: border-box; padding: 0px 5px;">139</li><li style="box-sizing: border-box; padding: 0px 5px;">140</li><li style="box-sizing: border-box; padding: 0px 5px;">141</li><li style="box-sizing: border-box; padding: 0px 5px;">142</li><li style="box-sizing: border-box; padding: 0px 5px;">143</li><li style="box-sizing: border-box; padding: 0px 5px;">144</li><li style="box-sizing: border-box; padding: 0px 5px;">145</li><li style="box-sizing: border-box; padding: 0px 5px;">146</li><li style="box-sizing: border-box; padding: 0px 5px;">147</li><li style="box-sizing: border-box; padding: 0px 5px;">148</li><li style="box-sizing: border-box; padding: 0px 5px;">149</li><li style="box-sizing: border-box; padding: 0px 5px;">150</li><li style="box-sizing: border-box; padding: 0px 5px;">151</li><li style="box-sizing: border-box; padding: 0px 5px;">152</li><li style="box-sizing: border-box; padding: 0px 5px;">153</li><li style="box-sizing: border-box; padding: 0px 5px;">154</li><li style="box-sizing: border-box; padding: 0px 5px;">155</li><li style="box-sizing: border-box; padding: 0px 5px;">156</li><li style="box-sizing: border-box; padding: 0px 5px;">157</li><li style="box-sizing: border-box; padding: 0px 5px;">158</li><li style="box-sizing: border-box; padding: 0px 5px;">159</li></ul>

  这里我们的密钥是直接写在代码中的,这样做其实是有风险的,因为一旦我们的项目被反编译,我们这里的密钥就变得很不安全了。这里有两种方法,一种是把密钥暴露给外部方法,即在读取数据和写入数据的时候使用同一个密钥即可,而密钥可以采取由机器MAC值生成的方法,这样每台机器上的密钥都是不同的可以防止数据被破解;其次可以采用DLL混淆的方法让反编译者无法看到代码中的内容,这样就无法获得正确的密钥从而无法获得存档里的内容了。

四、最终效果

好了,最后我们来写一个简单的测试脚本:

<code class="language-C# hljs cs has-numbering" style="display: block; padding: 0px; background-color: transparent; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-top-left-radius: 0px; border-top-right-radius: 0px; border-bottom-right-radius: 0px; border-bottom-left-radius: 0px; word-wrap: normal; background-position: initial initial; background-repeat: initial initial;"><span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> UnityEngine;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Collections;
<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">using</span> System.Collections.Generic;

<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> TestSave : MonoBehaviour {


    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"><summary></span></span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> 定义一个测试类</span>
    <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;"><span class="hljs-xmlDocTag" style="box-sizing: border-box;">///</span> <span class="hljs-xmlDocTag" style="box-sizing: border-box;"></summary></span></span>
    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">class</span> TestClass
    {
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> Name = <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"张三"</span>;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">float</span> Age = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">23.0</span>f;
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span> Sex = <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>;

        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">public</span> List<<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>> Ints = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> List<<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">int</span>> ()
        {
            <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">1</span>,
            <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">2</span>,
            <span class="hljs-number" style="color: rgb(0, 102, 102); box-sizing: border-box;">3</span>
        };
    }

    <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">void</span> Start () 
    {
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//定义存档路径</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> dirpath = Application.persistentDataPath + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/Save"</span>;
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//创建存档文件夹</span>
        IOHelper.CreateDirectory (dirpath);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//定义存档文件路径</span>
        <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">string</span> filename = dirpath + <span class="hljs-string" style="color: rgb(0, 136, 0); box-sizing: border-box;">"/GameData.sav"</span>;
        TestClass t = <span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">new</span> TestClass ();
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//保存数据</span>
        IOHelper.SetData (filename,t);
        <span class="hljs-comment" style="color: rgb(136, 0, 0); box-sizing: border-box;">//读取数据</span>
        TestClass t1 = (TestClass)IOHelper.GetData(filename,<span class="hljs-keyword" style="color: rgb(0, 0, 136); box-sizing: border-box;">typeof</span>(TestClass));

        Debug.Log(t1.Name);
        Debug.Log(t1.Age);
        Debug.Log(t1.Ints);
    }


}</code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; background-color: rgb(238, 238, 238); top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right;"><li style="box-sizing: border-box; padding: 0px 5px;">1</li><li style="box-sizing: border-box; padding: 0px 5px;">2</li><li style="box-sizing: border-box; padding: 0px 5px;">3</li><li style="box-sizing: border-box; padding: 0px 5px;">4</li><li style="box-sizing: border-box; padding: 0px 5px;">5</li><li style="box-sizing: border-box; padding: 0px 5px;">6</li><li style="box-sizing: border-box; padding: 0px 5px;">7</li><li style="box-sizing: border-box; padding: 0px 5px;">8</li><li style="box-sizing: border-box; padding: 0px 5px;">9</li><li style="box-sizing: border-box; padding: 0px 5px;">10</li><li style="box-sizing: border-box; padding: 0px 5px;">11</li><li style="box-sizing: border-box; padding: 0px 5px;">12</li><li style="box-sizing: border-box; padding: 0px 5px;">13</li><li style="box-sizing: border-box; padding: 0px 5px;">14</li><li style="box-sizing: border-box; padding: 0px 5px;">15</li><li style="box-sizing: border-box; padding: 0px 5px;">16</li><li style="box-sizing: border-box; padding: 0px 5px;">17</li><li style="box-sizing: border-box; padding: 0px 5px;">18</li><li style="box-sizing: border-box; padding: 0px 5px;">19</li><li style="box-sizing: border-box; padding: 0px 5px;">20</li><li style="box-sizing: border-box; padding: 0px 5px;">21</li><li style="box-sizing: border-box; padding: 0px 5px;">22</li><li style="box-sizing: border-box; padding: 0px 5px;">23</li><li style="box-sizing: border-box; padding: 0px 5px;">24</li><li style="box-sizing: border-box; padding: 0px 5px;">25</li><li style="box-sizing: border-box; padding: 0px 5px;">26</li><li style="box-sizing: border-box; padding: 0px 5px;">27</li><li style="box-sizing: border-box; padding: 0px 5px;">28</li><li style="box-sizing: border-box; padding: 0px 5px;">29</li><li style="box-sizing: border-box; padding: 0px 5px;">30</li><li style="box-sizing: border-box; padding: 0px 5px;">31</li><li style="box-sizing: border-box; padding: 0px 5px;">32</li><li style="box-sizing: border-box; padding: 0px 5px;">33</li><li style="box-sizing: border-box; padding: 0px 5px;">34</li><li style="box-sizing: border-box; padding: 0px 5px;">35</li><li style="box-sizing: border-box; padding: 0px 5px;">36</li><li style="box-sizing: border-box; padding: 0px 5px;">37</li><li style="box-sizing: border-box; padding: 0px 5px;">38</li><li style="box-sizing: border-box; padding: 0px 5px;">39</li><li style="box-sizing: border-box; padding: 0px 5px;">40</li><li style="box-sizing: border-box; padding: 0px 5px;">41</li><li style="box-sizing: border-box; padding: 0px 5px;">42</li><li style="box-sizing: border-box; padding: 0px 5px;">43</li><li style="box-sizing: border-box; padding: 0px 5px;">44</li><li style="box-sizing: border-box; padding: 0px 5px;">45</li></ul>

  脚本执行结果:

p1

  加密后游戏存档:

p2

  好了,这就是今天的内容了,希望大家能够喜欢,有什么问题可以给我留言,谢谢! 
  感谢风宇冲Unity3D教程宝典之两步实现超实用的XML存档一文提供相关思路!

喜欢我的博客请记住我的名字:秦元培,我的博客地址是:http://qinyuanpei.com 
转载请注明出处,本文作者:秦元培, 本文出处:http://blog.csdn.net/qinyuanpei/article/details/39717795


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值