Unity3D教程宝典之两步实现超实用的XML存档【引文】

2016/02/18 19:48
阅读数 173


使用方法非常简单:
把GameDataManager和XmlSaver两个脚本添加至工程后
(1)新建一个GameObject,起名GameDataManager并将GameDataManager脚本拖到上面。
(2)在GameDataManager里的GameData类中添加需要储存的数据
OK,跨平台防破解防拷贝的存档就搞定了!之后每次存档调用GameDataManager的Save函数,读档调用GameDataManager的Load函数。每次启动后GameDataManager会自动调用Load读档。如果玩家拿外来存档来覆盖本地存档,则游戏启动后数据清零,任何一次存档后作弊档被自动覆盖。注意:请勿放入二维以上数组,一般一维数据,枚举,自定义类 等等数据类型可放心添加。

【风宇冲】Unity3D教程宝典之两步实现超实用的XML存档


PS:风宇冲自己的U3d单机游戏和公司的单机游戏都用的这个XML存档,iOS,Android,PC,MAC都使用过的。放心使用吧。密钥的设定根据平台而定。

GameDataManager.cs的内容

    //=========================================================================================================
    //Note: Data Managing.
    //Date Created: 2012/04/17 by 风宇冲
    //Date Modified: 2012/12/14 by 风宇冲
    //=========================================================================================================
    using UnityEngine;
    using System.Collections;
    using System.IO;
    using System.Collections.Generic;
    using System;
    using System.Text;
    using System.Xml;
    using System.Security.Cryptography;
    //GameData,储存数据的类,把需要储存的数据定义在GameData之内就行//
    public class GameData
    {
        //密钥,用于防止拷贝存档//
        public string key;
       
        //下面是添加需要储存的内容//
        public string PlayerName;
        public float MusicVolume;
        public GameData()
        {
            PlayerName = "Player";
            MusicVolume = 0.6f;
        }
    }
    //管理数据储存的类//
    public class GameDataManager:MonoBehaviour
    {
        private string dataFileName ="tankyWarData.dat";//存档文件的名称,自己定//
        private  XmlSaver xs = new XmlSaver();
       
        public  GameData gameData;
       
        public void Awake()
        {
            gameData = new GameData();
           
            //设定密钥,根据具体平台设定//
            gameData.key = SystemInfo.deviceUniqueIdentifier;
            Load();
        }
       
        //存档时调用的函数//
        public  void Save()
        {
            string gameDataFile = GetDataPath() + "/"+dataFileName;
            string dataString= xs.SerializeObject(gameData,typeof(GameData));
            xs.CreateXML(gameDataFile,dataString);
        }
       
        //读档时调用的函数//
        public  void Load()
        {
            string gameDataFile = GetDataPath() + "/"+dataFileName;
            if(xs.hasFile(gameDataFile))
            {
               string dataString = xs.LoadXML(gameDataFile);
               GameData gameDataFromXML = xs.DeserializeObject(dataString,typeof(GameData)) as GameData;
               
                //是合法存档//
                 if(gameDataFromXML.key == gameData.key)
                {
                    gameData = gameDataFromXML;
                }
                //是非法拷贝存档//
                else
                {
                    //留空:游戏启动后数据清零,存档后作弊档被自动覆盖//
                }
            }
            else
            {
                if(gameData != null)
                Save();
            }
        }
       
        //获取路径//
        private static string GetDataPath()
        {
            // Your game has read+write access to /var/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/Documents
            // Application.dataPath returns ar/mobile/Applications/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/myappname.app/Data             
            // Strip "/Data" from path
            if(Application.platform == RuntimePlatform.IPhonePlayer)
            {
                string path = Application.dataPath.Substring (0, Application.dataPath.Length - 5);
                // Strip application name
                path = path.Substring(0, path.LastIndexOf('/'));
                return path + "/Documents";
            }
            else
            //    return Application.dataPath + "/Resources";
                return Application.dataPath;
        }
    }




                                         XmlSaver.cs的内容

    //=========================================================================================================
    //Note: XML processcing,  can not save multiple-array!!!
    //Date Created: 2012/04/17 by 风宇冲
    //Date Modified: 2012/04/19 by 风宇冲
    //=========================================================================================================
    using UnityEngine;
    using System.Collections;
    using System.Xml;
    using System.Xml.Serialization;
    using System.IO;
    using System.Text;
    using System.Security.Cryptography;
    using System;
    public class XmlSaver
    {   
        //内容加密
        public string Encrypt(string toE)
        {
            //加密和解密采用相同的key,具体自己填,但是必须为32位//
            byte[] keyArray = UTF8Encoding.UTF8.GetBytes("12348578902223367877723456789012");
            RijndaelManaged rDel = new RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = CipherMode.ECB;
            rDel.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = rDel.CreateEncryptor();
           
            byte[] toEncryptArray = UTF8Encoding.UTF8.GetBytes(toE);
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,0,toEncryptArray.Length);
       
            return Convert.ToBase64String(resultArray,0,resultArray.Length);
        }
       
        //内容解密
        public string Decrypt(string toD)
        {
            //加密和解密采用相同的key,具体值自己填,但是必须为32位//
            byte[] keyArray = UTF8Encoding.UTF8.GetBytes("12348578902223367877723456789012");
           
            RijndaelManaged rDel = new RijndaelManaged();
            rDel.Key = keyArray;
            rDel.Mode = CipherMode.ECB;
            rDel.Padding = PaddingMode.PKCS7;
            ICryptoTransform cTransform = rDel.CreateDecryptor();
           
            byte[] toEncryptArray = Convert.FromBase64String(toD);
            byte[] resultArray = cTransform.TransformFinalBlock(toEncryptArray,0,toEncryptArray.Length);
           
            return UTF8Encoding.UTF8.GetString(resultArray);
        }
       
        public string SerializeObject(object pObject,System.Type ty)
        {
           string XmlizedString   = null;
           MemoryStream memoryStream  = new MemoryStream();
           XmlSerializer xs  = new XmlSerializer(ty);
           XmlTextWriter xmlTextWriter  = new XmlTextWriter(memoryStream, Encoding.UTF8);
           xs.Serialize(xmlTextWriter, pObject);
           memoryStream = (MemoryStream)xmlTextWriter.BaseStream;
           XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());
           return XmlizedString;
        }
       
        public object DeserializeObject(string pXmlizedString , System.Type ty)
        {
           XmlSerializer xs  = new XmlSerializer(ty);
           MemoryStream memoryStream  = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));
           XmlTextWriter xmlTextWriter   = new XmlTextWriter(memoryStream, Encoding.UTF8);
           return xs.Deserialize(memoryStream);
        }
       
        //创建XML文件
        public void CreateXML(string fileName,string thisData)
        {
           string xxx = Encrypt(thisData);
           StreamWriter writer;
           writer = File.CreateText(fileName);
           writer.Write(xxx);
           writer.Close();
        }
       
        //读取XML文件
        public string LoadXML(string fileName)
        {
           StreamReader sReader = File.OpenText(fileName);
           string dataString = sReader.ReadToEnd();
           sReader.Close();
           string xxx = Decrypt(dataString);
           return xxx;
        }
       
        //判断是否存在文件
        public bool hasFile(String fileName)
        {
           return File.Exists(fileName);
        }
        public string UTF8ByteArrayToString(byte[] characters  )
        {    
           UTF8Encoding encoding  = new UTF8Encoding();
           string constructedString  = encoding.GetString(characters);
           return (constructedString);
        }
       
        public byte[] StringToUTF8ByteArray(String pXmlString )
        {
           UTF8Encoding encoding  = new UTF8Encoding();
           byte[] byteArray  = encoding.GetBytes(pXmlString);
           return byteArray;
        }
    }


展开阅读全文
打赏
1
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
1
分享
返回顶部
顶部