[经验分享] Unity3D结合XML载入和保存数据
保存工程的信息:比如游戏进程中的位置信息,对抗双方的个人信息等:
方法1:使用xml文件:
xml文件要以UTF-8的格式存储;
但是这样做会使得programmer 可以从脚本中控制xml文件中的所有的字符,包括xml文件中的语法命令字符,因此会带来不安全隐患;
附上两段代码:
A 这一段是我自己写的,将一个xml文件按照字符串读入;
虽然unity3d中的string类型说明中讲到保存的是unicode characters,但是实际上当xml文件比较大的时候,如果保存成unicode,就读不出来,如果保存成UTF-8就不存在这个问题;
using UnityEngine; using System.Collections; public class ReadXML: MonoBehaviour { //store the read in file WWW statusFile; //decide wether the reading of xml has been finished bool isReadIn = false; // Use this for initialization IEnumerator Start () {//不能用void,否则没有办法使用yield isReadIn = false; yield return StartCoroutine(ReadIn()); isReadIn = true; } IEnumerator ReadIn() { yield return statusFile = new WWW(“file:///D:/unity/rotationAndcolor/Assets/information/testxml.xml”);//注意路径的写法 } // Update is called once per frame void Update () { if(isReadIn) { string statusData = statusFile.data; print(statusData.Length); } } //get the parameters in the xml file void getPatameters(string _xmlString) { //_xmlString.[0] } void postParameters() { } } using UnityEngine; using System.Collections; using System.Xml; using System.Xml.Serialization; using System.IO; using System.Text; public class _GameSaveLoad: MonoBehaviour { // An example where the encoding can be found is at // We will just use the KISS method and cheat a little and use // the examples from the web page since they are fully described // This is our local private members Rect _Save, _Load, _SaveMSG, _LoadMSG; bool _ShouldSave, _ShouldLoad,_SwitchSave,_SwitchLoad; string _FileLocation,_FileName; public GameObject _Player; UserData myData; string _PlayerName; string _data; Vector3 VPosition; // When the EGO is instansiated the Start will trigger // so we setup our initial values for our local members void Start () { // We setup our rectangles for our messages _Save=new Rect(10,80,100,20); _Load=new Rect(10,100,100,20); _SaveMSG=new Rect(10,120,400,40); _LoadMSG=new Rect(10,140,400,40); // Where we want to save and load to and from _FileLocation=Application.dataPath; _FileName=“SaveData.xml”; // for now, lets just set the name to Joe Schmoe _PlayerName = “Joe Schmoe”; // we need soemthing to store the information into myData=new UserData(); } void Update () {} void OnGUI() { //*************************************************** // Loading The Player... // ************************************************** if (GUI.Button(_Load,“Load”)) { GUI.Label(_LoadMSG,“Loading from: ”+_FileLocation); // Load our UserData into myData LoadXML(); if(_data.ToString() != “”) { // notice how I use a reference to type (UserData) here, you need this // so that the returned object is converted into the correct type myData = (UserData)DeserializeObject(_data); // set the players position to the data we loaded VPosition=new Vector3(myData._iUser.x,myData._iUser.y,myData._iUser.z); _Player.transform.position=VPosition; // just a way to show that we loaded in ok Debug.Log(myData._iUser.name); } } //*************************************************** // Saving The Player... // ************************************************** if (GUI.Button(_Save,“Save”)) { GUI.Label(_SaveMSG,“Saving to: ”+_FileLocation); myData._iUser.x=_Player.transform.position.x; myData._iUser.y=_Player.transform.position.y; myData._iUser.z=_Player.transform.position.z; myData._iUser.name=_PlayerName; // Time to creat our XML! _data = SerializeObject(myData); // This is the final resulting XML from the serialization process CreateXML(); Debug.Log(_data); } } /* The following metods came from the referenced URL */ string UTF8ByteArrayToString(byte[] characters) { UTF8Encoding encoding = new UTF8Encoding(); string constructedString = encoding.GetString(characters); return (constructedString); } byte[] StringToUTF8ByteArray(string pXmlString) { UTF8Encoding encoding = new UTF8Encoding(); byte[] byteArray = encoding.GetBytes(pXmlString); return byteArray; } // Here we serialize our UserData object of myData string SerializeObject(object pObject) { string XmlizedString = null; MemoryStream memoryStream = new MemoryStream(); XmlSerializer xs = new XmlSerializer(typeof(UserData)); XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); xs.Serialize(xmlTextWriter, pObject); memoryStream = (MemoryStream)xmlTextWriter.BaseStream; XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray()); return XmlizedString; } // Here we deserialize it back into its original form object DeserializeObject(string pXmlizedString) { XmlSerializer xs = new XmlSerializer(typeof(UserData)); MemoryStream memoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString)); XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); return xs.Deserialize(memoryStream); } // Finally our save and load methods for the file itself void CreateXML() { StreamWriter writer; FileInfo t = new FileInfo(_FileLocation+“\\”+ _FileName); if(!t.Exists) { writer = t.CreateText(); } else { t.Delete(); writer = t.CreateText(); } writer.Write(_data); writer.Close(); Debug.Log(“File written.”); } void LoadXML() { StreamReader r = File.OpenText(_FileLocation+“\\”+ _FileName); string _info = r.ReadToEnd(); r.Close(); _data=_info; Debug.Log(“File Read”); } } // UserData is our custom class that holds our defined objects we want to store in XML format public class UserData { // We have to define a default instance of the structure public DemoData _iUser; // Default constructor doesn't really do anything at the moment public UserData() { } // Anything we want to store in the XML file, we define it here public struct DemoData { public float x; public float y; public float z; public string name; } } 以下是javascript版本 import System; import System.Collections; import System.Xml; import System.Xml.Serialization; import System.IO; import System.Text; // Anything we want to store in the XML file, we define it here class DemoData { var x : float; var y : float; var z : float; var name : String; } // UserData is our custom class that holds our defined objects we want to store in XML format class UserData { // We have to define a default instance of the structure public var _iUser : DemoData = new DemoData(); // Default constructor doesn't really do anything at the moment function UserData() { } } //public class GameSaveLoad: MonoBehaviour { // An example where the encoding can be found is at // We will just use the KISS method and cheat a little and use // the examples from the web page since they are fully described // This is our local private members private var _Save : Rect; private var _Load : Rect; private var _SaveMSG : Rect; private var _LoadMSG : Rect; //var _ShouldSave : boolean; //var _ShouldLoad : boolean; //var _SwitchSave : boolean; //var _SwitchLoad : boolean; private var _FileLocation : String; private var _FileName : String = “SaveData.xml”; //public GameObject _Player; var _Player : GameObject; var _PlayerName : String = “Joe Schmoe”; private var myData : UserData; private var _data : String; private var VPosition : Vector3; // When the EGO is instansiated the Start will trigger // so we setup our initial values for our local members //function Start () { function Awake () { // We setup our rectangles for our messages _Save=new Rect(10,80,100,20); _Load=new Rect(10,100,100,20); _SaveMSG=new Rect(10,120,200,40); _LoadMSG=new Rect(10,140,200,40); // Where we want to save and load to and from _FileLocation=Application.dataPath; // we need soemthing to store the information into myData=new UserData(); } function Update () {} function OnGUI() { // *************************************************** // Loading The Player... // ************************************************** if (GUI.Button(_Load,“Load”)) { GUI.Label(_LoadMSG,“Loading from: ”+_FileLocation); // Load our UserData into myData LoadXML(); if(_data.ToString() != “”) { // notice how I use a reference to type (UserData) here, you need this // so that the returned object is converted into the correct type //myData = (UserData)DeserializeObject(_data); myData = DeserializeObject(_data); // set the players position to the data we loaded VPosition=new Vector3(myData._iUser.x,myData._iUser.y,myData._iUser.z); _Player.transform.position=VPosition; // just a way to show that we loaded in ok Debug.Log(myData._iUser.name); } } // *************************************************** // Saving The Player... // ************************************************** if (GUI.Button(_Save,“Save”)) { GUI.Label(_SaveMSG,“Saving to: ”+_FileLocation); //Debug.Log(“SaveLoadXML: sanity check:”+ _Player.transform.position.x); myData._iUser.x = _Player.transform.position.x; myData._iUser.y = _Player.transform.position.y; myData._iUser.z = _Player.transform.position.z; myData._iUser.name = _PlayerName; // Time to creat our XML! _data = SerializeObject(myData); // This is the final resulting XML from the serialization process CreateXML(); Debug.Log(_data); } } /* The following metods came from the referenced URL */ //string UTF8ByteArrayToString(byte[] characters) function UTF8ByteArrayToString(characters : byte[] ) { var encoding : UTF8Encoding = new UTF8Encoding(); var constructedString : String = encoding.GetString(characters); return (constructedString); } //byte[] StringToUTF8ByteArray(string pXmlString) function StringToUTF8ByteArray(pXmlString : String) { var encoding : UTF8Encoding = new UTF8Encoding(); var byteArray : byte[] = encoding.GetBytes(pXmlString); return byteArray; } // Here we serialize our UserData object of myData //string SerializeObject(object pObject) function SerializeObject(pObject : Object) { var XmlizedString : String = null; var memoryStream : MemoryStream = new MemoryStream(); var xs : XmlSerializer = new XmlSerializer(typeof(UserData)); var xmlTextWriter : XmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); xs.Serialize(xmlTextWriter, pObject); memoryStream = xmlTextWriter.BaseStream; // (MemoryStream) XmlizedString = UTF8ByteArrayToString(memoryStream.ToArray()); return XmlizedString; } // Here we deserialize it back into its original form //object DeserializeObject(string pXmlizedString) function DeserializeObject(pXmlizedString : String) { var xs : XmlSerializer = new XmlSerializer(typeof(UserData)); var memoryStream : MemoryStream = new MemoryStream(StringToUTF8ByteArray(pXmlizedString)); var xmlTextWriter : XmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8); return xs.Deserialize(memoryStream); } // Finally our save and load methods for the file itself function CreateXML() { var writer : StreamWriter; //FileInfo t = new FileInfo(_FileLocation+“\\”+ _FileName); var t : FileInfo = new FileInfo(_FileLocation+“/”+ _FileName); if(!t.Exists) { writer = t.CreateText(); } else { t.Delete(); writer = t.CreateText(); } writer.Write(_data); writer.Close(); Debug.Log(“File written.”); } function LoadXML() { //StreamReader r = File.OpenText(_FileLocation+“\\”+ _FileName); var r : StreamReader = File.OpenText(_FileLocation+“/”+ _FileName); var _info : String = r.ReadToEnd(); r.Close(); _data=_info; Debug.Log(“File Read”); } //}
方法2:使用unity 3d 的ISerializable类
它的好处是,可以将文件存成自己定义的后缀形式,并且2进制化存储,在U3D的帮助文档中有相关介绍
- 下一篇:【游戏优化】均衡好这四个方向
- 上一篇:Unity委托简单例子