这是场景存储的信息类,创建好不管它
using UnityEngine;
using System.Collections;
[SerializeField]public class Sence//场景存储的变量放这个类里
{
Public Vector3 cubePosion; //Cube位置信息
}
这是GameDataManager类,游戏日志控制器。
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 bool isDu;//点击读档为True,加载场景后为False
//场景存储内容
public Sence s;
public GameData()
{
s = new Sence ();//存储内容初始化,只能放构造函数
isDu = false;
}
}
//管理数据储存的类//
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类,用于管理XML。创建就可以,不需要操作。
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 :MonoBehaviour{
//内容加密
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;
}
}
这是场景里的存储内容
using UnityEngine;
using System.Collections;
[SerializeField]public class Sence{
//Cube的存储内容
public Vector3 cubePosion;//正方形的坐标
}
场景如图
场景里有一个Cube,两个4方形,两个4方形是为了方便对照Cube的位置。
调整摄像机角度,能看到Cube。
建一个空物体,用来加载GameDataManager(游戏日志控制器),和XmlSaver类。
给Cube写一个保存读取类(游戏日志控制器是对游戏数据的操作,所以只能改变部分数据,这个类用于改变Cube的部分数据)
using UnityEngine;
using System.Collections;
public class SaveCube : MonoBehaviour {
public void Save(){//保存Cube的部分数据,这里保存Cube的位置信息
GameObject cube = GameObject.Find("Cube");//获得Cube对象
GameObject gameDataManager = GameObject.Find ("GameDataManager");//获得GameDataManager(游戏控制器)对象
GameDataManager g = gameDataManager.GetComponent<GameDataManager>();//获得GameDataManager(游戏控制器)脚本
g.gameData.s.cubePosion = cube.transform.position;//保存Cube的位置
}
public void Load(){//场景开始时加载游戏对象
GameObject cube = GameObject.Find("Cube");//获得Cube对象
GameObject gameDataManager = GameObject.Find ("GameDataManager");//获得GameDataManager(游戏控制器)对象
GameDataManager g = gameDataManager.GetComponent<GameDataManager>();//获得GameDataManager(游戏控制器)脚本
if(g.gameData.isDu == true){//如果是读档状态
cube.transform.position = g.gameData.s.cubePosion;//读取Cube的位置,并赋值给Cube
}
}
}
这是以场景为单位的(场景初始化,游戏日志保存)
using UnityEngine;
using System.Collections;
public class SenceData : MonoBehaviour {
void Start () {//初始化场景
//Cube信息的初始化
SaveCube sc = gameObject.GetComponent<SaveCube>();
sc.Load ();
//末尾设置默认不读挡
GameObject gameDataManager = GameObject.Find ("GameDataManager");
GameDataManager g = gameDataManager.GetComponent<GameDataManager> ();
g.gameData.isDu = false;
g.Save ();
}
public void Save (){//存档数据
//Cube信息的保存
SaveCube sc = gameObject.GetComponent<SaveCube>();
sc.Save();
}
}
建一个空物体用于加载SenceData类,SaveCube类,如图
这是选择读档 存档 默认场景的UI类(就是用于用户操作的按钮设置)
using UnityEngine;
using System.Collections;
public class UI : MonoBehaviour {
private GameDataManager g;//定义GameDataManager(游戏控制器)脚本
private SenceData s;//定义SenceData(场景加载器)脚本
public int senceNum;
// Use this for initialization
void Start () {
GameObject gameDataManager = GameObject.Find ("GameDataManager");//获得GameDataManager(游戏控制器)对象
g = gameDataManager.GetComponent<GameDataManager>();//获得GameDataManager(游戏控制器)脚本
GameObject senceData = GameObject.Find ("SenceData");//获得SenceData(场景加载器)对象
s = senceData.GetComponent<SenceData>();//获得SenceData(场景加载器)脚本
}
void OnGUI(){
if(GUI.Button (new Rect(Screen.width/2-110,Screen.height/2-150,50,50),"存")){
s.Save ();//场景提交数据
g.Save ();//日志保存
}
if(GUI.Button (new Rect(Screen.width/2+110,Screen.height/2-150,50,50),"读")){
g.gameData.isDu = true;//设置为可读档状态
g.Save ();//日志保存为可读档状态
UnityEngine.SceneManagement.SceneManager.LoadScene (senceNum);//加载场景
}
if(GUI.Button (new Rect(Screen.width/2-50,Screen.height/2-150,100,50),"默认场景")){
UnityEngine.SceneManagement.SceneManager.LoadScene (senceNum);//加载场景
}
}
}
建一个空物体加载UI类,如图
这里我把SenceNum设置成0
保存场景,如图
然后File ->Build Settings..->Add Open Sence,如图
这个存档的例子就做好了
运行时图为
保持运行,通过场景移动Cube,如图
回到游戏,点击存按钮,再点读。
获取了保存的位置,再点默认回到了原来的点。自己看看想想原理。