1. 程式人生 > >Unity 儲存和載入XML檔案

Unity 儲存和載入XML檔案

儲存工程的資訊:比如遊戲程序中的位置資訊,對抗雙方的個人資訊等:

方法1:使用xml檔案:

 xml檔案要以UTF-8的格式儲存;

 但是這樣做會使得programmer 可以從指令碼中控制xml檔案中的所有的字元,包括xml檔案中的語法命令字元,因此會帶來不安全隱患;

 附上兩段程式碼:

 A 這一段是我自己寫的,將一個xml檔案按照字串讀入;

雖然unity3d中的string型別說明中講到儲存的是unicode characters,但是實際上當xml檔案比較大的時候,如果儲存成unicode,就讀不出來,如果儲存成UTF-8就不存在這個問題;

C#版本:

              using
 UnityEngine;   
  1. using System.Collections;   
  2. using System.Xml;   
  3. using System.Xml.Serialization;   
  4. using System.IO;   
  5. using System.Text;   
  6. publicclass ReadXML: MonoBehaviour {  
  7.  //store the read in file 
  8.  WWW statusFile;  
  9.  //decide wether the reading of  xml has been finished
  10.     bool isReadIn = false;  
  11.  // Use this for initialization
  12.  IEnumerator Start () {//不能用void,否則沒有辦法使用yield
  13.   isReadIn = false;  
  14.   yield return StartCoroutine(ReadIn());  
  15.   isReadIn = true;  
  16.  }  
  17.  IEnumerator ReadIn()  
  18.  {  
  19.   yield return statusFile = new WWW("file:///D:/unity/rotationAndcolor/Assets/information/testxml.xml");//注意路徑的寫法  
  20.  }  
  21.  // Update is called once per frame
  22.  void Update () {  
  23.   if(isReadIn)  
  24.   {  
  25.    string statusData = statusFile.data;  
  26.    print(statusData.Length);  
  27.    }  
  28.  }  
  29.  //get the parameters in the xml file
  30.  void getPatameters(string _xmlString)  
  31.  {  
  32.   //_xmlString.[0] 
  33.   }  
  34.  void postParameters()  
  35.  {  
  36.   }  
  37. }  
  38. publicclass _GameSaveLoad: MonoBehaviour {   
  39.    // An example where the encoding can be found is at 
  40.    // http://www.eggheadcafe.com/articles/system.xml.xmlserialization.asp 
  41.    // We will just use the KISS method and cheat a little and use 
  42.    // the examples from the web page since they are fully described 
  43.    // This is our local private members 
  44.    Rect _Save, _Load, _SaveMSG, _LoadMSG;   
  45.    bool _ShouldSave, _ShouldLoad,_SwitchSave,_SwitchLoad;   
  46.    string _FileLocation,_FileName;   
  47.    public GameObject _Player;   
  48.    UserData myData;   
  49.    string _PlayerName;   
  50.    string _data;   
  51.    Vector3 VPosition;   
  52.    // When the EGO is instansiated the Start will trigger 
  53.    // so we setup our initial values for our local members 
  54.    void Start () {   
  55.       // We setup our rectangles for our messages 
  56.       _Save=new Rect(10,80,100,20);   
  57.       _Load=new Rect(10,100,100,20);   
  58.       _SaveMSG=new Rect(10,120,400,40);   
  59.       _LoadMSG=new Rect(10,140,400,40);   
  60.       // Where we want to save and load to and from 
  61.       _FileLocation=Application.dataPath;   
  62.       _FileName="SaveData.xml";   
  63.       // for now, lets just set the name to Joe Schmoe 
  64.       _PlayerName = "Joe Schmoe";   
  65.       // we need soemthing to store the information into 
  66.       myData=new UserData();   
  67.    }   
  68.    void Update () {}   
  69.    void OnGUI()   
  70.    {      
  71.    //*************************************************** 
  72.    // Loading The Player... 
  73.    // **************************************************       
  74.    if (GUI.Button(_Load,"Load")) {   
  75.       GUI.Label(_LoadMSG,"Loading from: "+_FileLocation);   
  76.       // Load our UserData into myData 
  77.       LoadXML();   
  78.       if(_data.ToString() != "")   
  79.       {   
  80.         // notice how I use a reference to type (UserData) here, you need this 
  81.         // so that the returned object is converted into the correct type 
  82.         myData = (UserData)DeserializeObject(_data);   
  83.         // set the players position to the data we loaded 
  84.         VPosition=new Vector3(myData._iUser.x,myData._iUser.y,myData._iUser.z);                
  85.         _Player.transform.position=VPosition;   
  86.         // just a way to show that we loaded in ok 
  87.         Debug.Log(myData._iUser.name);   
  88.       }   
  89.    }   
  90.    //*************************************************** 
  91.    // Saving The Player... 
  92.    // **************************************************    
  93.    if (GUI.Button(_Save,"Save")) {   
  94.      GUI.Label(_SaveMSG,"Saving to: "+_FileLocation);   
  95.      myData._iUser.x=_Player.transform.position.x;   
  96.      myData._iUser.y=_Player.transform.position.y;   
  97.      myData._iUser.z=_Player.transform.position.z;   
  98.      myData._iUser.name=_PlayerName;      
  99.      // Time to creat our XML! 
  100.      _data = SerializeObject(myData);   
  101.      // This is the final resulting XML from the serialization process 
  102.      CreateXML();   
  103.      Debug.Log(_data);   
  104.    }   
  105.    }   
  106.    /* The following metods came from the referenced URL */   
  107.    string UTF8ByteArrayToString(byte[] characters)   
  108.    {        
  109.       UTF8Encoding encoding = new UTF8Encoding();   
  110.       string constructedString = encoding.GetString(characters);   
  111.       return (constructedString);   
  112.    }   
  113.    byte[] StringToUTF8ByteArray(string pXmlString)   
  114.    {   
  115.       UTF8Encoding encoding = new UTF8Encoding();   
  116.       byte[] byteArray = encoding.GetBytes(pXmlString);   
  117.       return byteArray;   
  118.    }   
  119.    // Here we serialize our UserData object of myData 
  120.    string SerializeObject(object pObject)   
  121.    {   
  122.       string XmlizedString = null;   
  123.       MemoryStream memoryStream = new MemoryStream();   
  124.       XmlSerializer xs = new XmlSerializer(typeof(UserData));   
  125.       XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);   
  126.       xs.Serialize(xmlTextWriter, pObject);   
  127.       memoryStream = (MemoryStream)xmlTextWriter.BaseStream;   
  128.       XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());   
  129.       return XmlizedString;   
  130.    }   
  131.    // Here we deserialize it back into its original form 
  132.    object DeserializeObject(string pXmlizedString)   
  133.    {   
  134.       XmlSerializer xs = new XmlSerializer(typeof(UserData));   
  135.       MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));   
  136.       XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8);   
  137.       return xs.Deserialize(memoryStream);   
  138.    }   
  139.    // Finally our save and load methods for the file itself 
  140.    void CreateXML()   
  141.    {   
  142.       StreamWriter writer;   
  143.       FileInfo t = new FileInfo(_FileLocation+"//"+ _FileName);   
  144.       if(!t.Exists)   
  145.       {   
  146.          writer = t.CreateText();   
  147.       }   
  148.       else
  149.       {   
  150.          t.Delete();   
  151.          writer = t.CreateText();   
  152.       }   
  153.       writer.Write(_data);   
  154.       writer.Close();   
  155.       Debug.Log("File written.");   
  156.    }   
  157.    void LoadXML()   
  158.    {   
  159.       StreamReader r = File.OpenText(_FileLocation+"//"+ _FileName);   
  160.       string _info = r.ReadToEnd();   
  161.       r.Close();   
  162.       _data=_info;   
  163.       Debug.Log("File Read");   
  164.    }   
  165. }   
  166. // UserData is our custom class that holds our defined objects we want to store in XML format 
  167.  publicclass UserData   
  168.  {   
  169.     // We have to define a default instance of the structure 
  170.    public DemoData _iUser;   
  171.     // Default constructor doesn't really do anything at the moment 
  172.    public UserData() { }   
  173.    // Anything we want to store in the XML file, we define it here 
  174.    publicstruct DemoData   
  175.    {   
  176.       publicfloat x;   
  177.       publicfloat y;   
  178.       publicfloat z;   
  179.       publicstring name;   
  180.    }   

js 版本:

             import System;  
  1. import System.Collections;  
  2. import System.Xml;  
  3. import System.Xml.Serialization;  
  4. import System.IO;  
  5. import System.Text;  
  6. // Anything we want to store in the XML file, we define it here
  7. class DemoData  
  8. {  
  9.     var x : float;  
  10.     var y : float;  
  11.     var z : float;  
  12.     var name : String;  
  13. }  
  14. // UserData is our custom class that holds our defined objects we want to store in XML format
  15.  class UserData  
  16.  {  
  17.     // We have to define a default instance of the structure
  18.    publicvar _iUser : DemoData = new DemoData();  
  19.     // Default constructor doesn't really do anything at the moment
  20.    function UserData() { }  
  21. }  
  22. //public class GameSaveLoad: MonoBehaviour {
  23. // An example where the encoding can be found is at
  24. // http://www.eggheadcafe.com/articles/system.xml.xmlserialization.asp
  25. // We will just use the KISS method and cheat a little and use
  26. // the examples from the web page since they are fully described
  27. // This is our local private members
  28. privatevar _Save : Rect;  
  29. privatevar _Load : Rect;  
  30. privatevar _SaveMSG : Rect;  
  31. privatevar _LoadMSG : Rect;  
  32. //var _ShouldSave : boolean;
  33. //var _ShouldLoad : boolean;
  34. //var _SwitchSave : boolean;
  35. //var _SwitchLoad : boolean;
  36. privatevar _FileLocation : String;  
  37. privatevar _FileName : String = "SaveData.xml";  
  38. //public GameObject _Player;
  39. var _Player : GameObject;  
  40. var _PlayerName : String = "Joe Schmoe";  
  41. privatevar myData : UserData;  
  42. privatevar _data : String;  
  43. privatevar VPosition : Vector3;  
  44. // When the EGO is instansiated the Start will trigger
  45. // so we setup our initial values for our local members
  46. //function Start () {
  47. function Awake () {   
  48.       // We setup our rectangles for our messages
  49.       _Save=new Rect(10,80,100,20);  
  50.       _Load=new Rect(10,100,100,20);  
  51.       _SaveMSG=new Rect(10,120,200,40);  
  52.       _LoadMSG=new Rect(10,140,200,40);  
  53.       // Where we want to save and load to and from
  54.       _FileLocation=Application.dataPath;  
  55.       // we need soemthing to store the information into
  56.       myData=new UserData();  
  57.    }  
  58. function Update () {}  
  59. function OnGUI()  
  60. {     
  61.    // ***************************************************
  62.    // Loading The Player...
  63.    // **************************************************       
  64.    if (GUI.Button(_Load,"Load")) {  
  65.       GUI.Label(_LoadMSG,"Loading from: "+_FileLocation);  
  66.       // Load our UserData into myData
  67.       LoadXML();  
  68.       if(_data.ToString() != "")  
  69.       {  
  70.          // notice how I use a reference to type (UserData) here, you need this
  71.          // so that the returned object is converted into the correct type
  72.          //myData = (UserData)DeserializeObject(_data);
  73.          myData = DeserializeObject(_data);  
  74.          // set the players position to the data we loaded
  75.          VPosition=new Vector3(myData._iUser.x,myData._iUser.y,myData._iUser.z);               
  76.          _Player.transform.position=VPosition;  
  77.          // just a way to show that we loaded in ok
  78.          Debug.Log(myData._iUser.name);  
  79.       }  
  80.    }  
  81.    // ***************************************************
  82.    // Saving The Player...
  83.    // **************************************************   
  84.    if (GUI.Button(_Save,"Save")) {  
  85.       GUI.Label(_SaveMSG,"Saving to: "+_FileLocation);  
  86.       //Debug.Log("SaveLoadXML: sanity check:"+ _Player.transform.position.x);
  87.       myData._iUser.x = _Player.transform.position.x;  
  88.       myData._iUser.y = _Player.transform.position.y;  
  89.       myData._iUser.z = _Player.transform.position.z;  
  90.       myData._iUser.name = _PlayerName;     
  91.       // Time to creat our XML!
  92.       _data = SerializeObject(myData);  
  93.       // This is the final resulting XML from the serialization process
  94.       CreateXML();  
  95.       Debug.Log(_data);  
  96.    }  
  97. }  
  98. /* The following metods came from the referenced URL */
  99. //string UTF8ByteArrayToString(byte[] characters)
  100. function UTF8ByteArrayToString(characters : byte[] )  
  101. {       
  102.    var encoding : UTF8Encoding  = new UTF8Encoding();  
  103.    var constructedString : String  = encoding.GetString(characters);  
  104.    return (constructedString);  
  105. }  
  106. //byte[] StringToUTF8ByteArray(string pXmlString)
  107. function StringToUTF8ByteArray(pXmlString : String)  
  108. {  
  109.    var encoding : UTF8Encoding  = new UTF8Encoding();  
  110.    var byteArray : byte[]  = encoding.GetBytes(pXmlString);  
  111.    return byteArray;  
  112. }  
  113.    // Here we serialize our UserData object of myData
  114.    //string SerializeObject(object pObject)
  115. function SerializeObject(pObject : Object)  
  116. {  
  117.    var XmlizedString : String  = null;  
  118.    var memoryStream : MemoryStream  = new MemoryStream();  
  119.    var xs : XmlSerializer = new XmlSerializer(typeof(UserData));  
  120.    var xmlTextWriter : XmlTextWriter  = new XmlTextWriter(memoryStream, Encoding.UTF8);  
  121.    xs.Serialize(xmlTextWriter, pObject);  
  122.    memoryStream = xmlTextWriter.BaseStream; // (MemoryStream)
  123.    XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray());  
  124.    return XmlizedString;  
  125. }  
  126.    // Here we deserialize it back into its original form
  127.    //object DeserializeObject(string pXmlizedString)
  128. function DeserializeObject(pXmlizedString : String)     
  129. {  
  130.    var xs : XmlSerializer  = new XmlSerializer(typeof(UserData));  
  131.    var memoryStream : MemoryStream  = new MemoryStream(StringToUTF8ByteArray(pXmlizedString));  
  132.    var xmlTextWriter : XmlTextWriter  = new XmlTextWriter(memoryStream, Encoding.UTF8);  
  133.    return xs.Deserialize(memoryStream);  
  134. }  
  135.    // Finally our save and load methods for the file itself
  136. function CreateXML()  
  137. {  
  138.    var writer : StreamWriter;  
  139.    //FileInfo t = new FileInfo(_FileLocation+"//"+ _FileName);
  140.    var t : FileInfo = new FileInfo(_FileLocation+"/"+ _FileName);  
  141.    if(!t.Exists)  
  142.    {  
  143.       writer = t.CreateText();  
  144.    }  
  145.    else
  146.    {  
  147.       t.Delete();  
  148.       writer = t.CreateText();  
  149.    }  
  150.    writer.Write(_data);  
  151.    writer.Close();  
  152.    Debug.Log("File written.");  
  153. }  
  154. function LoadXML()  
  155. {  
  156.    //StreamReader r = File.OpenText(_FileLocation+"//"+ _FileName);
  157.    var r : StreamReader = File.OpenText(_FileLocation+"/"+ _FileName);  
  158.    var _info : String = r.ReadToEnd();  
  159.    r.Close();  
  160.    _data=_info;  
  161.    Debug.Log("File Read");  
  162. }  
  163. //}

方法2:使用unity 3d 的ISerializable類

它的好處是,可以將檔案存成自己定義的字尾形式,並且2進位制化儲存,在u3d的幫助文件中有相關介紹。