這是場景存儲的信息類,創建好不管它
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,如圖
回到游戲,點擊存按鈕,再點讀。
獲取了保存的位置,再點默認回到了原來的點。自己看看想想原理。