유니티에서 XML파싱을 위해 WWW 클래스로 .XML 파일을 불러왔습니다. 불러들인 정보를 디시리얼라이즈하는 기능은 없나요?(안드로이드폰을 위해 개발중입니다.)
조회수 3516회
IEnumerator read()
{
Text txt = GameObject.Find("ERRORMESSAGE2").GetComponent<Text>();
string fileName = "Quests.xml";
string filePath = "jar:file://" + Application.dataPath + "!/assets/" + fileName;
var www = new WWW(filePath);
yield return www;
if (!string.IsNullOrEmpty(www.error))
{
txt.text = "로딩실패";
}
else if (string.IsNullOrEmpty(www.error))
{
txt.text = "로딩성공";
}
}
불러들였습니다만 아래 iostream같이 디시리얼라이즈 하는 기능은 없나요?
void serialize()
{
Type[ ] questType = { typeof(QUEST) };
XmlSerializer serializer = new XmlSerializer(typeof(QuestContainer), questType);
TextReader textReader = new StreamReader(filePath);
QuestContainer = (QuestContainer)serializer.Deserialize(textReader);
textReader.Close();
txt.text = (textReader.ReadLine());
}
불러들인 정보를 아래 양식에 맞게 디시리얼라이즈하는 기능이 필요합니다..
정보는 불러들여진 후 각 프로쎄스로 나눠져 컨테이너로 들어가게됩니다..
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; }
}
}
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;
}
<?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>
그런 기능이 없다면 수작업으로 주입하는 방법이라도 알려주시면 좋겠습니다.
추가사항 -
-
-
(•́ ✖ •̀)
알 수 없는 사용자 - 〉
4 답변
-
XmlSerialization을 이용하는게 좋겠네요. 안드로이드에서 loadXML()까지는 확인했고 write는 유니티에디터에서만 동작 확인해 봤습니다.
참고로 List에서 아이템을 지울때는 반복문에서 지우면 안되더군요. tmp만들어서 옮긴담에 지웠으니 코드 확인요.
using UnityEngine; using System.Collections; using System.Xml; using System.Collections.Generic; using System.Xml.Serialization; using System.IO; public class NewBehaviourScript : MonoBehaviour { QuestContainer container; void Start () { loadXML (); List<QUEST> tmp = new List<QUEST> (); foreach (QUEST quest in container.Confirmed) { container.Complete.Add (quest); tmp.Add (quest); } foreach (QUEST quest in tmp) { container.Confirmed.Remove (quest); } writeXML (); } void loadXML(){ 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(); Debug.Log ("Confirmed"); foreach (QUEST quest in container.Confirmed) { Debug.Log (quest.Questname); } Debug.Log ("Complete"); foreach (QUEST quest in container.Complete) { Debug.Log (quest.Questname); } } void writeXML(){ var serializer = new XmlSerializer (typeof(QuestContainer)); var stream = new FileStream(pathForDocumentsFile("tmp.xml"), FileMode.Create); serializer.Serialize(stream, 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); } } }
수정: 더 좋은 방법 발견해서 아래 방법은 별로인것 같네요.
코드에 IEnumerator가 있는걸 보니...유니티에서 작업중이셨네요. 다음과 같이 하시면 될것 같습니다.
using UnityEngine; using System.Collections; using System.Xml; using System.Collections.Generic; public class XMLParsing : MonoBehaviour{ QuestContainer qc; void Awake(){ qc = new QuestContainer(); } void parseXML(Text txt){ XmlDocument xmlDoc = new XmlDocument(); xmlDoc.LoadXml(txt); XmlNodeList xnList; //Confirmed xnList= xml.SelectNodes("/QuestContainer/Confirmed/QUEST"); foreach(XmlNode node in xnList) { Quest quest = new Quest(); quest.QuestName = xn["QuestName"].InnerText; quest.Level = int.Parse(xn["Level"].InnerText); qc.confirmed.Add(quest); } //같은 방식으로 Complete, Possible, impossible처리 } }
-
유니티에서 파일을 불러들이시려면 Resources폴더에 파일을 넣어 두어야 합니다. Assets아래에 Resources폴더가 없으시면 만드시고, 그 안에 XML파일을 넣어두세요. 그리고 다음 코드를 참고해서 QuestContainer로 XML을 읽어들이도록 만들면 됩니다. http://www.w3schools.com/xml/cd_catalog.xml 에서 받을 수 있는 xml파일을 Resources폴더에 Catalog.xml로 넣어 두었습니다. 참고로 Resources에서 파일을 읽어올때는 확장자를 안붙여줘도 되요.
유니티에서 돌려본 코드니까 잘 될겁니다.
using UnityEngine; using System.Collections; using System.Xml; using System.Collections.Generic; public class NewBehaviourScript : MonoBehaviour { List<CD> confirmed= new List<CD>(); // Use this for initialization void Start () { parseXML (); } // Update is called once per frame void Update () { } void parseXML(){ TextAsset textAsset = (TextAsset) Resources.Load("Catalog"); XmlDocument xmlDoc = new XmlDocument (); xmlDoc.LoadXml ( textAsset.text ); XmlNodeList xnList; //Confirmed xnList= xmlDoc.SelectNodes("/CATALOG/CD"); foreach(XmlNode node in xnList) { CD cd = new CD(); cd.title = node["TITLE"].InnerText; Debug.Log(cd.title); cd.artist = node["ARTIST"].InnerText; confirmed.Add(cd); } //같은 방식으로 Complete, Possible, impossible처리 } } public class CD{ public string title; public string artist; }
질문을 올려주실때, 모두 코드로 올려주시면 더 자세히 설명이 가능할 것 같은데, XML파일은 이미지 캡쳐로 올려주시고, Quest클래스의 정의도 안올려주시니 어쩔수 없이 다른 파일을 예로 들었네요.
- 질문에 대한 내용은 댓글로 달아주시면 좋겠습니다. 정토드 2016.2.16 11:19
- 알겠습니다. 이 사이트가 아직 적응이 안되서 뭐가 어떻게 돌아가는지를 모르겠네요. 알 수 없는 사용자 2016.2.16 11:57
-
TextAsset textAsset = (TextAsset) Resources.Load("Catalog"); XmlDocument xmlDoc = new XmlDocument (); xmlDoc.LoadXml ( textAsset.text );
이 경로가 접근이 안된다고 하셨는데요. 유니티에서 폴더 구조를 이렇게 만드신게 맞나요? Resource에 있는 모든 파일은 안드로이드로빌드 하더라도 접근이 가능합니다.
- 질문 맨 아랫부분에 사진 추가했습니다.TextAsset textAsset = (TextAsset) Resources.Load("/xml/Catalog"); XmlDocument xmlDoc = new XmlDocument (); xmlDoc.LoadXml ( textAsset.text ); 이 되겠죠. 알 수 없는 사용자 2016.2.16 12:26
-
방금 제가 올려드렸던 코드 빌드해서 실행해보니 안드로이드에서 잘 동작합니다. Resources에 있는 내용을 TextAsset으로 읽어오는게 왜 안되는지는 잘 모르겠네요. 너무 당연히 되어야 하는 부분이라서요.
안드로이드 폰에서 돌리면서 로그 찍어본 부분 첨부합니다. Catalog.xml파일에서 Title만
Debug.Log
로 찍고 있었는데 곡 이름이 찍히는게 잘 보입니다.02-16 13:07:53.387 3637-3652/? D/Unity﹕ RGB GL_EXT_sRGB_write_control GL_EXT_texture_sRGB_decode GL_EXT_texture_filter_anisotropic GL_EXT_multisampled_render_to_texture GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_EXT_disjoint_timer_query 02-16 13:07:54.357 3637-3652/? I/Unity﹕ Empire Burlesque (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Hide your heart (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Greatest Hits (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Still got the blues (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Eros (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ One night only (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Sylvias Mother (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Maggie May (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Romanza (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ When a man loves a woman (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Black angel (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ 1999 Grammy Nominees (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ For the good times (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Big Willie style (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Tupelo Honey (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Soulsville (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ The very best of (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Stop (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Bridge of Spies (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Private Dancer (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Midt om natten (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Pavarotti Gala Concert (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ The dock of the bay (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Picture book (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65) 02-16 13:07:54.367 3637-3652/? I/Unity﹕ Red
- xml파일을 txt파일로 바꿔주니 되네요..; 뭔 이유인지.. 답변 감사드립니다. 알 수 없는 사용자 2016.2.16 20:00
- 혹시 기왕 이렇게 된거 시리얼라이즈 하는 방법도 알 수 있을 까요 ㅡ,ㅡ.. QuestContainer에 있는 리스트 별로 xml에 저장되어야 하는데, 설마 node를 하나씩 만들어서 아예 새로운 xml파일을 만들어야 하는겁니까? iostream을 이용 못하니 여간 불편한게아니네요. 알 수 없는 사용자 2016.2.16 21:14
- 제 xml 파일에 있는데로 보면, 시작이라는 questname을 가진 노드를 찾아서 하위 노드들을 전부 possible로 옮긴다거나, confrim으로 옮긴다거나 하는기능이 있으면 좋을텐데요. 알 수 없는 사용자 2016.2.16 22:40
- 스레드가 길어져서 첫번쨰 답변을 수정했습니다. 정토드 2016.2.17 11:33
- 답변 갑사드립니다. 어디서 구한 정보이신지 혹시 알 수 있으면 좋겠네요. pathForDocumentsFile에 있는 안드로이드 path는 resource인가요 streamingassets인가요? 알 수 없는 사용자 2016.2.17 16:12
- 정보는 구글링해서 찾아봤어요. 이거저거의 조합이라 딱히 소스가 어딘지를 말씀드리기가 애매하네요. Unity Xml serialize로 검색했어요.안드로이드 파일이 어디 저장되는지는 저도 잘 모르겠네요. 정토드 2016.2.17 16:29
댓글 입력