2016-08-02 102 views
1

我有一個json對象,我不知道對象中的鍵是什麼,有沒有辦法使用Unity的JsonUtility來解碼這樣的對象?使用未知鍵解碼Json對象

這裏是我有什麼,但它不工作:

[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):

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

鍵是「未知」的原因是因爲這是一個用於翻譯的json文件,並且由於每個遊戲具有不同的遊戲玩法,這意味着每個遊戲中的文本也是不同的,並且鍵的數量也會不同。這也是我必須管理的一個sdk,它將被放入許多遊戲中。

+0

您是否真的不知道模式是什麼,或者您知道「如果屬性'X'具有'Foo'的值,那麼我知道json描述了一個'Foo'對象,並且可以將其作爲一個對象進行去除處理,或者你有一系列物品,但你不知道該數組中會有多少物品。這是非常罕見的,你會*不知道*輸入是什麼。 –

+0

@ScottChamberlain我不知道密鑰的原因是因爲我正在管理許多遊戲的sdk,並且每個遊戲都需要翻譯,因此每個項目都有一個密鑰(一個用於翻譯的標識符,比如'score')和一個值(翻譯後的文字,如「Score」或「得分了」或「Гол」)。由於每場比賽都不同,所有的鍵也會不同。 –

回答

2

根據您的意見,您真正需要的是兩個級別的序列化,一個級別代表每個翻譯的單詞,另一個級別代表單詞陣列。

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

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

這會轉換到JSON一旦反序列化對象Translation你可以將其轉換爲一個字典快速查找看起來類似於

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

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

你需要某種可預測的結構。你可以嘗試一個簡單的數組(參見我的更新),但我不知道unity是否支持直接或不是直接數組。 –

+0

從我讀過的根項目需要成爲一個對象。 –