유니티에서 XML파싱을 위해 WWW 클래스로 .XML 파일을 불러왔습니다. 불러들인 정보를 디시리얼라이즈하는 기능은 없나요?(안드로이드폰을 위해 개발중입니다.)


 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>

그런 기능이 없다면 수작업으로 주입하는 방법이라도 알려주시면 좋겠습니다.

추가사항 -

alt text

  • 2016년 06월 01일에 수정됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 요즘은 개발은 주로 레일즈 사이트 수정하는 일을 하고, 예전에는 모바일 게임도 조금 만들어 봤습니다.
  • 2016년 02월 15일에 작성됨

  • 수정 감사합니다.    정두식   2016.2.16 11:54     
조회수 1185


Kakao codefestival banner

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처리
  }
}
  • 2016년 02월 15일에 작성됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 요즘은 개발은 주로 레일즈 사이트 수정하는 일을 하고, 예전에는 모바일 게임도 조금 만들어 봤습니다.


유니티에서 파일을 불러들이시려면 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년 02월 16일에 작성됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 요즘은 개발은 주로 레일즈 사이트 수정하는 일을 하고, 예전에는 모바일 게임도 조금 만들어 봤습니다.

  • 질문에 대한 내용은 댓글로 달아주시면 좋겠습니다.    정두식   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에 있는 모든 파일은 안드로이드로빌드 하더라도 접근이 가능합니다.

alt text

  • 2016년 02월 16일에 작성됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 요즘은 개발은 주로 레일즈 사이트 수정하는 일을 하고, 예전에는 모바일 게임도 조금 만들어 봤습니다.

  • 질문 맨 아랫부분에 사진 추가했습니다.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


  • 2016년 02월 16일에 작성됨
    루비와 파이썬을 좋아합니다. 새로운 언어를 배우는것도 좋아해요. 요즘은 개발은 주로 레일즈 사이트 수정하는 일을 하고, 예전에는 모바일 게임도 조금 만들어 봤습니다.

  • 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     

로그인이 필요한 기능입니다.

Hashcode는 개발자들을 위한 무료 QnA사이트 입니다. 작성한 답변에 다른 개발자들이 댓글을 작성하거나 좋아요/싫어요를 할 수 있기 때문에 계정을 필요로 합니다.
► 로그인
► 계정만들기
Close