2016-08-02 5 views
1

json 객체가 있는데 객체의 키가 무엇인지 전혀 알지 못합니다. 유니티의 JsonUtility를 사용하여 객체를 디코드 할 수있는 방법이 있습니까? 여기 알 수없는 키가있는 Json 객체 디코드

내가 무슨이지만, 그것은 작동하지 않습니다

{ 
    "one": "First Item", 
    "two": "Second Item" 
} 
:

[RequireComponent(typeof(Text))] 
public class GameSmartTranslate : MonoBehaviour { 

    public string translationKey; 

    Text text; 

    // Use this for initialization 
    void Start() { 
     text = GetComponent<Text>(); 
     GetTranslationFile(); 
    } 

    void GetTranslationFile(){ 
     string lang = GameSmart.Web.Locale(true); 
     TextAsset transFile = Resources.Load<TextAsset>("Text/" + lang); 
     Trans items = JsonUtility.FromJson<Trans>(transFile.text); 
    } 

} 

[System.SerializableAttribute] 
class Trans { 
    public string key; 
    public string value; 
} 

테스트 JSON 파일 (파일 키 개 이상의 가능성이 onetwo되지 않습니다) 다음과 같습니다

키가 "알 수 없음"인 이유는 번역을위한 json 파일이기 때문이며 각 게임마다 다른 게임 플레이가 있기 때문에 각 게임마다 텍스트가 다르다는 것과 키 수가 또한 다를 것임을 의미합니다 . 이것은 또한 많은 게임에 투입 될 관리해야하는 SDK에 대한 것입니다.

+0

당신은 정말로 스키마가 무엇인지 모르거나 "속성'X'가'Foo'의 값을 가지고 있다면 json이'Foo' 객체를 설명하고 하나로서 제거 될 수 있음을 알고 있습니다." 또는 항목 배열이 있지만 배열에 얼마나 많은 항목이 있는지 알 수 없습니다. 입력이 될 생각이 전혀 없다는 것은 극히 드문 일입니다. –

+0

@ScottChamberlain 많은 게임에서 SDK를 관리하고 각 게임을 번역해야하므로 각 항목에 키 ('점수'와 같은 번역 식별자)가 있기 때문에 키를 모르는 이유는 무엇입니까? 값 ('점수'또는 '수득률'또는 'Гол'와 같은 번역 된 텍스트). 각 게임이 다르기 때문에 모든 키가 다를 것입니다. –

답변

2

귀하의 의견을 바탕으로 실제로 필요한 것은 두 가지 수준의 직렬화입니다. 하나의 수준은 각 번역 된 단어를 나타내며 다른 하나는 단어 배열을 보유합니다.

[Serializable] 
public class Word{ 
    public string key; 
    public string value; 
} 

[Serializable] 
public class Translation 
{ 
    public Word[] wordList; 
} 

은 당신이 당신의 Translation 목적은 당신이 빠른 조회를 위해 사전에 변환 할 수 역 직렬화되면

{ 
    "wordList": [ 
     { 
     "key": "Hello!", 
     "value": "¡Hola!" 
     }, 
     { 
     "key": "Goodbye", 
     "value": "Adiós" 
     } 
    ] 
} 

비슷한 모양 JSON에 번역 될 것이다. 키의 번역되지 않은 단어를 만듦으로써

Translation items = JsonUtility.FromJson<Translation>(transFile.text); 
Dictionary<string, string> transDict = items.wordList.ToDictionary(x=>x.key, y=>y.value); 

는 사전에 번역 된 단어를 검색하는 확장 방법을 쉽게하지만 하나를 찾을 수없는 경우이 키를 사용합니다.

public static class ExtensionMethods 
{ 
    public static string GetTranslationOrDefault(this Dictionary<string, string> dict, string word) 
    { 
     string result; 
     if(!dict.TryGetValue(word, out result) 
     { 
      //Word was not in the dictionary, return the key. 
      result = word; 
     } 
     return result; 
    } 
} 

당신이

[RequireComponent(typeof(Text))] 
public class GameSmartTranslate : MonoBehaviour { 

    public string translationKey; 

    Text text; 

    void Start() { 
     text = GetComponent<Text>(); 
     Dictionary<string, string> transDict = GetTranslationFile(); 

     //If the translation is not defined the text is set to translationKey 
     text.text = transDict.GetTranslationOrDefault(translationKey); 
    } 

    Dictionary<string, string> GetTranslationFile(){ 
     string lang = GameSmart.Web.Locale(true); 
     TextAsset transFile = Resources.Load<TextAsset>("Text/" + lang); 
     Translation items = JsonUtility.FromJson<Translation>(transFile.text); 
     Dictionary<string, string> transDict = items.wordList.ToDictionary(x=>x.key, y=>y.value); 
     return transDict; 
    } 
} 

처럼 사용할 수있는 당신은 GameSmartTranslate에서 사전 코드를 이동 시도하고 사전마다 재 구축되지 않도록 싱글 게임 객체에 넣어 할 수 있습니다 이 스크립트가있는 레이블.


업데이트 :

당신은 또한 JSON

[{ 
    "key": "Hello!", 
    "value": "¡Hola!" 
}, { 
    "key": "Goodbye", 
    "value": "Adiós" 
}] 

이 당신이 Translation 클래스를 제거하고 코드가

Word[] items = JsonUtility.FromJson<Word[]>(transFile.text); 
과 같을 것이다 할 것을 사용하여 시도 할 수

하지만 전 Unity 5.3 배열 형식에서 직접 작동하지 않습니다. 5.4로 시도하지 않았습니다.

+0

이것은 내가하고있는 일이기 때문에 객체의 배열 없이는 할 수 없다. –

+0

예측 가능한 구조가 필요합니다. 벌거 벗은 배열 (내 업데이트 참조)을 시도해 볼 수는 있지만, 단결이 배열을 desearalizing하는 것을 직접 지원하는지 여부는 알 수 없습니다. –

+0

루트 항목을 읽었을 때 객체가되어야합니다. –