유니티3D 안드로이드 플랫폼 XML WRITE LOAD 질문입니다.
조회수 3328회
string filename = "Quests";
Type[] questType = { typeof(QUEST) };
FileStream fs = new FileStream(Path.Combine(Application.persistentDataPath,filename+".txt"), FileMode.Create);
StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
XmlSerializer serializer = new XmlSerializer(typeof(QuestContainer), questType);
serializer.Serialize(sw, questContainer);
sw.Close();
위는 지정된 파일에 WRITE하기 위한 방법입니다.
string filename = "Quests";
Type[] questType = { typeof(QUEST) };
XmlSerializer serializer = new XmlSerializer(typeof(QuestContainer), questType);
TextReader fs = new StreamReader(Application.persistentDataPath + filename + ".txt");
QuestContainer = (QuestContainer)serializer.Deserialize(fs);
fs.Close();
위는 지정된 파일을 LOAD하기 위한 방법입니다.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class QuestContainer
{
private List<QUEST> confirmed = new List<QUEST>();
private List<QUEST> complete = new List<QUEST>();
private List<QUEST> possible = new List<QUEST>();
private List<QUEST> im_possible = new List<QUEST>();
public List<QUEST> Confirmed
{
get { return confirmed; }
set { confirmed = value; }
}
public List<QUEST> Complete
{
get { return complete; }
set { complete = value; }
}
public List<QUEST> Possible
{
get { return possible; }
set { possible = value; }
}
public List<QUEST> im_Possible
{
get { return im_possible; }
set { im_possible = value; }
}
}
위는 QuestContainer 클래스입니다.
public class QUEST
{
public string Questname { get; set; }
public string Description { get; set; }
public string Class { get; set; }
public int Level { get; set; }
public int STR { get; set; }
public int CON { get; set; }
public int INT { get; set; }
public int WIS { get; set; }
public int DEX { get; set; }
public string Title { get; set; }
public string Item { get; set; }
public QUEST_TYPE questType { get; set; }
public DIFFICULTY difficulty { get; set; }
public EXPEDIENT eXPEDIENT { get; set; }
public QUEST_REWARD questReward { get; set; }
public string target { get; set; }
public int count { get; set; }
public bool canClear { get; set; }
public QUEST()
{
}
public QUEST(string Questname,string Description,string Class,int level,int str,int con, int Int, int wis, int dex,string title,string item, QUEST_TYPE QuestType, DIFFICULTY Difficulty, QUEST_REWARD quest_reward, EXPEDIENT EXPEDIENT, string Target, int Count, bool canclear)
{
this.Description = Description;
this.Questname = Questname;
this.questType = QuestType;
this.difficulty = Difficulty;
this.eXPEDIENT = EXPEDIENT;
this.questReward = quest_reward;
this.Class = Class;
this.Level = level;
this.STR = str;
this.CON = con;
this.INT = Int;
this.WIS = wis;
this.DEX = dex;
this.Title = title;
this.Item = item;
this.target = Target;
this.count = Count;
this.canClear = canclear;
}
}
위는 Quest클래스입니다.
<?xml version="1.0" encoding="utf-8"?>
<QuestContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Confirmed>
<QUEST>
<Questname>시작</Questname>
<Description>이제 시작이에요!</Description>
<Class>ALL</Class>
<Level>0</Level>
<STR>0</STR>
<CON>0</CON>
<INT>0</INT>
<WIS>0</WIS>
<DEX>0</DEX>
<Title />
<Item />
<questType>ROOP</questType>
<difficulty>EASY</difficulty>
<eXPEDIENT>MOVE</eXPEDIENT>
<questReward>GOLD</questReward>
<target>Bank</target>
<count>10</count>
<canClear>false</canClear>
</QUEST>
</Confirmed>
<Complete />
<Possible />
<im_Possible />
</QuestContainer>
위는 xml파일 입니다. 안드로이드 플랫폼에선 .txt로 변경하여 사용중입니다.
QuestContainer의 리스트에 따라 4가지 프로세스로 나뉘어 xml파일에 저장이됩니다.
read는 이상없이 잘 되나,
게임 중 QuestContainer에 리스트 내용을 바꿔주고 write를 해주는데,
다시 불러올 때 아무 변경이 없는 내용이 불러와지는걸 보니, write에 문제가 있는 것 같은데 이유를 알 수 없네요.
-
(•́ ✖ •̀)
알 수 없는 사용자
1 답변
-
다음과 같이 하니 안드로이드에서 잘 동작하네요. 파일의 내용을 불러와서 값을 바꿔서 쓴 다음 다시 불러와서 출력해 봤습니다.
pathForDocumentsFile에서 경로를 불러오세요. 그리고 파일을 불러올때 실패하게되면 resources의 파일을 불러오는 방식을 이용했습니다.
using UnityEngine; using System.Collections; using System.Xml; using System.Collections.Generic; using System.Xml.Serialization; using System.IO; using System.Text; using System; public class NewBehaviourScript : MonoBehaviour { QuestContainer container; void Start () { loadXML (); Debug.Log ("###before###"); foreach (QUEST quest in container.Confirmed) { Debug.Log (quest.Description); quest.Description="!!!"+quest.Description; } writeXML (); loadXML (); Debug.Log ("###after###"); foreach (QUEST quest in container.Confirmed) { Debug.Log (quest.Description); } } void loadXML(){ try{ TextReader fs = new StreamReader(pathForDocumentsFile("Catalog.txt")); var serializer = new XmlSerializer(typeof(QuestContainer)); container = serializer.Deserialize(fs) as QuestContainer; fs.Close(); } catch(Exception e){ TextAsset textAsset = (TextAsset) Resources.Load("Catalog"); var serializer = new XmlSerializer(typeof(QuestContainer)); StringReader stream = new StringReader (textAsset.ToString ()); container = serializer.Deserialize(stream) as QuestContainer; stream.Close(); } } void writeXML(){ var serializer = new XmlSerializer (typeof(QuestContainer)); var stream = new FileStream(pathForDocumentsFile("Catalog.txt"), FileMode.Create); StreamWriter sw = new StreamWriter (stream, Encoding.UTF8); serializer.Serialize(sw, container); stream.Close(); } public string pathForDocumentsFile( string filename ) { if (Application.platform == RuntimePlatform.IPhonePlayer) { string path = Application.dataPath.Substring( 0, Application.dataPath.Length - 5 ); path = path.Substring( 0, path.LastIndexOf( '/' ) ); return Path.Combine( Path.Combine( path, "Documents" ), filename ); } else if(Application.platform == RuntimePlatform.Android) { string path = Application.persistentDataPath; path = path.Substring(0, path.LastIndexOf( '/' ) ); return Path.Combine (path, filename); } else { string path = Application.dataPath; path = path.Substring(0, path.LastIndexOf( '/' ) ); return Path.Combine (path, filename); } } }
그리고 serializer를 이용하기 위해서는 각 클래스에 다음과 같은 annotation을 붙여주어야 합니다.
using System.Xml.Serialization; using System.Collections.Generic; [XmlRoot("QuestContainer")] public class QuestContainer{ [XmlArray("Confirmed")] [XmlArrayItem("QUEST")] public List<QUEST> Confirmed = new List<QUEST> (); } public class QUEST{ public string Questname; public string Description; public int Level; }
- 정말 토나오네요. 프로그램 로직짜는것보다 파일 하나 입출력하는게 더 힘드니 무슨 .. 화딱지나서 죽겠네요. annotation을 붙일 때 리스트 별로 하나씩 붙이는 겁니까? 답변 감사합니다. 지금은 너무 고통스러워서 있다가 실행 확인하겠습니다.. 알 수 없는 사용자 2016.2.18 18:09
- 네. 리스트별로 다 따로 붙입니다. 정토드 2016.2.18 18:43
- 아 정말 감사합니다.. ㅡㅡ write가 안되는게 annotation을 안 붙여준 것 때문이었나요? application.persistent로 접근한 것은 같은데.. 왜 안되는지 이유를 알 수 없었는데 아 쾌감 때문에 미치겠네요. 알 수 없는 사용자 2016.2.18 20:02
- Json를 사용하시면 훨씬 편하게 할 수 있을거 같습니다. https://github.com/SaladLab/Json.Net.Unity3D 이놈 한번 써보세용. 알 수 없는 사용자 2016.3.15 23:22
댓글 입력