Unity3d存檔例子


這是場景存儲的信息類,創建好不管它

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,如圖

 

回到游戲,點擊存按鈕,再點讀。

獲取了保存的位置,再點默認回到了原來的點。自己看看想想原理。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM