本文轉自666666666
這是場景存儲的信息類,創建好不管它
using?UnityEngine;
using?System.Collections;
[SerializeField]public class Sence//場景存儲的變量放這個類里
{
Public Vector3cubePosion;//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(游戲控制器)腳本
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(游戲控制器)腳本
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();
sc.Load?();
//末尾設置默認不讀擋
GameObject?gameDataManager?=?GameObject.Find?("GameDataManager");
GameDataManager?g?=?gameDataManager.GetComponent?();
g.gameData.isDu?=?false;
g.Save?();
}
public?void?Save?(){//存檔數據
//Cube信息的保存
SaveCube?sc?=?gameObject.GetComponent();
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(游戲控制器)腳本
GameObject?senceData?=?GameObject.Find?("SenceData");//獲得SenceData(場景加載器)對象
s?=?senceData.GetComponent();//獲得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,如圖
回到游戲,點擊存按鈕,再點讀。
獲取了保存的位置,再點默認回到了原來的點。自己看看想想原理。