原创文章如需转载请注明:转载自风宇冲Unity3D教程学院
本套存档的优点:易使用,跨平台,防作弊(内容加密 + 防拷贝)
脚本下载地址
使用方法非常简单:
把GameDataManager和XmlSaver两个脚本添加至工程 后
(1)新建一个GameObject,起名GameDataManager并将GameDataManager脚本拖到上面。
(2)在GameDataManager里的GameData类中添加需要储存的数据
OK,跨平台防破解防拷贝的存档就搞定了 !之后 每次存档 调用GameDataManager 的Save函数, 读档 调用GameDataManager 的Load函数。每次启动后GameDataManager 会自动调用Load读档。如果玩家拿外来存档来覆盖本地存档 ,则游戏启动后数据清零 ,任何一次存档后作弊档被自动覆盖 。注意:请勿放入二维以上数组 ,一般一维数据,枚举,自定义类 等等数据类型可放心添加 。
![【风宇冲】Unity3D教程宝典之两步实现超实用的XML存档 【风宇冲】Unity3D教程宝典之两步实现超实用的XML存档](https://i-blog.csdnimg.cn/blog_migrate/fd7fecc62122eb5781930250caf647c5.jpeg)
PS:风宇冲自己的U3d单机游戏和公司的单机游戏都用的这个 XML存档,iOS,Android,PC,MAC都使用过的。放心使用吧。密钥的设定根据平台而定 。
附:脚本代码
- //=========================================================================================================
- //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; -
} - }
- //=========================================================================================================
- //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("123485789022233678777234 56789012"); -
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("123485789022233678777234 56789012"); -
-
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; -
} - }