U3DC.COM | 优三帝研究院

Menu

[经验分享] 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的帮助文档中有相关介绍

打赏
— 于 共写了9828个字
— 文内使用到的标签:

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据