转载自风宇冲Unity3D教程学院
两步实现超实用的XML存档
本套存档的优点:易使用,跨平台,防作弊(内容加密 + 防拷贝)
使用方法非常简单:
把GameDataManager和XmlSaver两个脚本添加至工程后
(1)新建一个GameObject,起名GameDataManager并将GameDataManager脚本拖到上面。
(2)在GameDataManager里的GameData类中添加需要储存的数据
OK,跨平台防破解防拷贝的存档就搞定了!之后每次存档调用GameDataManager的Save函数,读档调用GameDataManager的Load函数。每次启动后GameDataManager会自动调用Load读档。如果玩家拿外来存档来覆盖本地存档,则游戏启动后数据清零,任何一次存档后作弊档被自动覆盖。注意:请勿放入二维以上数组,一般一维数据,枚举,自定义类 等等数据类型可放心添加。
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;
- }
- }
时间: 2024-10-07 07:04:23