web-dev-qa-db-ja.com

UnityでJsonおよびJson配列をシリアライズおよびデシリアライズする

私はPHPファイルからWWWを使って1に送るアイテムのリストを持っています。

WWW.textは以下のようになります。

[
    {
        "playerId": "1",
        "playerLoc": "Powai"
    },
    {
        "playerId": "2",
        "playerLoc": "Andheri"
    },
    {
        "playerId": "3",
        "playerLoc": "Churchgate"
    }
]

ここで、stringから余分な[]を削除します。 Boomlagoon.JSONを使用して解析しようとすると、最初のオブジェクトだけが取得されます。私はリストをdeserialize()しなければならないこととMiniJSONをインポートしたことを知りました。

しかし、私はこのリストをdeserialize()する方法を混同しています。すべてのJSONオブジェクトをループ処理してデータを取得したいです。 C#を使ってUnityでこれを行うにはどうすればよいですか?

私が使っているクラスは

public class player
{
    public string playerId { get; set; }
    public string playerLoc { get; set; }
    public string playerNick { get; set; }
}

[]をトリミングした後、私はMiniJSONを使用してJSONを解析することができます。しかし、それは最初のKeyValuePairだけを返しています。

IDictionary<string, object> players = Json.Deserialize(serviceData) as IDictionary<string, object>;

foreach (KeyValuePair<string, object> kvp in players)
{
    Debug.Log(string.Format("Key = {0}, Value = {1}", kvp.Key, kvp.Value));
}

ありがとうございます。

73
dil33pm

Unityは、5.3.3アップデート後にAPIに JsonUtility を追加しました。もっと複雑なことをしているのでなければ、すべてのサードパーティのライブラリを忘れてください。 JsonUtilityは、他のJsonライブラリよりも高速です。 Unity5.3.3バージョン以上にアップデートしてから、以下の解決策を試してください。

JsonUtilityは軽量のAPIです。単純型のみがサポートされています。辞書などのコレクションをサポートしますnot。 1つの例外はListです。 ListおよびList配列をサポートしています!

Dictionaryをシリアル化する必要がある場合、または単純なデータ型をシリアル化および逆シリアル化する以外のことを行う場合は、サードパーティAPIを使用してください。それ以外の場合は、読み続けてください。

直列化するクラスの例:

[Serializable]
public class Player
{

    public string playerId;
    public string playerLoc;
    public string playerNick;
}

1。 1つのデータオブジェクト(非配列JSON)

パートAのシリアル化

Serialize public static string ToJson(object obj); メソッドでJsonに。

Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";

//Convert to Jason
string playerToJason = JsonUtility.ToJson(playerInstance);
Debug.Log(playerToJason);

出力

{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}

パートBのシリアル化

Serialize public static string ToJson(object obj, bool prettyPrint); メソッドオーバーロードを使用してJsonに。 trueJsonUtility.ToJson関数に渡すだけで、データがフォーマットされます。下の出力を上の出力と比較してください。

Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";

//Convert to Jason
string playerToJason = JsonUtility.ToJson(playerInstance, true);
Debug.Log(playerToJason);

出力

{
    "playerId": "8484239823",
    "playerLoc": "Powai",
    "playerNick": "Random Nick"
}

パートAのデシリアライズ

デシリアライズpublic static T FromJson(string json); メソッドのオーバーロードを伴うjson。

string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = JsonUtility.FromJson<Player>(jsonString);
Debug.Log(player.playerLoc);

パートBのデシリアライズ

デシリアライズpublic static object FromJson(string json, Type type); メソッドのオーバーロードを伴うjson。

string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player));
Debug.Log(player.playerLoc);

パートCのデシリアライズ

デシリアライズpublic static void FromJsonOverwrite(string json, object objectToOverwrite); メソッドを使用したjson。 JsonUtility.FromJsonOverwriteを使用すると、デシリアライズするオブジェクトの新しいインスタンスは作成されません。渡されたインスタンスを単純に再利用し、その値を上書きします。

これは効率的であり、可能であれば使用する必要があります。

Player playerInstance;
void Start()
{
    //Must create instance once
    playerInstance = new Player();
    deserialize();
}

void deserialize()
{
    string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";

    //Overwrite the values in the existing class instance "playerInstance". Less memory Allocation
    JsonUtility.FromJsonOverwrite(jsonString, playerInstance);
    Debug.Log(playerInstance.playerLoc);
}

2。複数のデータ(ARRAY JSON)

Jsonには複数のデータオブジェクトが含まれています。たとえば、playerIdonceよりも多く出現しました。 UnityのJsonUtilityはまだ新しいため配列をサポートしていませんが、この人から helper クラスを使用してarrayを取得できますJsonUtilityで。

JsonHelperというクラスを作成します。 JsonHelperを下から直接コピーします。

public static class JsonHelper
{
    public static T[] FromJson<T>(string json)
    {
        Wrapper<T> wrapper = JsonUtility.FromJson<Wrapper<T>>(json);
        return wrapper.Items;
    }

    public static string ToJson<T>(T[] array)
    {
        Wrapper<T> wrapper = new Wrapper<T>();
        wrapper.Items = array;
        return JsonUtility.ToJson(wrapper);
    }

    public static string ToJson<T>(T[] array, bool prettyPrint)
    {
        Wrapper<T> wrapper = new Wrapper<T>();
        wrapper.Items = array;
        return JsonUtility.ToJson(wrapper, prettyPrint);
    }

    [Serializable]
    private class Wrapper<T>
    {
        public T[] Items;
    }
}

Jsonアレイのシリアル化

Player[] playerInstance = new Player[2];

playerInstance[0] = new Player();
playerInstance[0].playerId = "8484239823";
playerInstance[0].playerLoc = "Powai";
playerInstance[0].playerNick = "Random Nick";

playerInstance[1] = new Player();
playerInstance[1].playerId = "512343283";
playerInstance[1].playerLoc = "User2";
playerInstance[1].playerNick = "Rand Nick 2";

//Convert to Jason
string playerToJason = JsonHelper.ToJson(playerInstance, true);
Debug.Log(playerToJason);

出力

{
    "Items": [
        {
            "playerId": "8484239823",
            "playerLoc": "Powai",
            "playerNick": "Random Nick"
        },
        {
            "playerId": "512343283",
            "playerLoc": "User2",
            "playerNick": "Rand Nick 2"
        }
    ]
}

Jsonアレイのデシリアライズ

string jsonString = "{\r\n    \"Items\": [\r\n        {\r\n            \"playerId\": \"8484239823\",\r\n            \"playerLoc\": \"Powai\",\r\n            \"playerNick\": \"Random Nick\"\r\n        },\r\n        {\r\n            \"playerId\": \"512343283\",\r\n            \"playerLoc\": \"User2\",\r\n            \"playerNick\": \"Rand Nick 2\"\r\n        }\r\n    ]\r\n}";

Player[] player = JsonHelper.FromJson<Player>(jsonString);
Debug.Log(player[0].playerLoc);
Debug.Log(player[1].playerLoc);

出力

ポワイ

User2


これがサーバーからのJson配列であり、手動で作成しなかった場合

受信した文字列の前に{"Items":を追加し、最後に}を追加する必要がある場合があります。

このための簡単な関数を作成しました。

string fixJson(string value)
{
    value = "{\"Items\":" + value + "}";
    return value;
}

それからあなたはそれを使うことができます:

string jsonString = fixJson(yourJsonFromServer);
Player[] player = JsonHelper.FromJson<Player>(jsonString);

3。クラスなしでJSON文字列を逆シリアル化&&数値プロパティでJSONを逆シリアル化

これは、数値または数値のプロパティで始まるJSONです。

例えば:

{ 
"USD" : {"15m" : 1740.01, "last" : 1740.01, "buy" : 1740.01, "sell" : 1744.74, "symbol" : "$"}, 

"ISK" : {"15m" : 179479.11, "last" : 179479.11, "buy" : 179479.11, "sell" : 179967, "symbol" : "kr"},

"NZD" : {"15m" : 2522.84, "last" : 2522.84, "buy" : 2522.84, "sell" : 2529.69, "symbol" : "$"}
}

UnityのJsonUtilityは、「15m」プロパティが数字で始まるため、これをサポートしていません。クラス変数は整数で始めることはできません。

Unityの wiki からSimpleJSON.csをダウンロードします。

USDの「15m」プロパティを取得するには:

var N = JSON.Parse(yourJsonString);
string price = N["USD"]["15m"].Value;
Debug.Log(price);

ISKの「15m」プロパティを取得するには:

var N = JSON.Parse(yourJsonString);
string price = N["ISK"]["15m"].Value;
Debug.Log(price);

NZDの「15m」プロパティを取得するには:

var N = JSON.Parse(yourJsonString);
string price = N["NZD"]["15m"].Value;
Debug.Log(price);

数字で始まらない残りのJsonプロパティは、UnityのJsonUtilityで処理できます。


4。JsonUtilityのトラブルシューティング:

JsonUtility.ToJsonでシリアル化するときの問題

{}で空の文字列または「JsonUtility.ToJson」を取得しますか?

A。クラスが配列ではないことを確認してください。その場合は、JsonHelper.ToJsonの代わりにJsonUtility.ToJsonを使用して上記のヘルパークラスを使用します。

B。シリアル化するクラスの先頭に[Serializable]を追加します。

C。クラスからプロパティを削除します。たとえば、変数のpublic string playerId { get; set; }remove{ get; set; }。 Unityはこれをシリアル化できません。

JsonUtility.FromJsonでデシリアライズする際の問題

ANullを取得する場合は、JsonがJson配列でないことを確認してください。その場合は、JsonHelper.FromJsonの代わりにJsonUtility.FromJsonを使用して上記のヘルパークラスを使用します。

B。デシリアライズ中にNullReferenceExceptionを取得する場合は、クラスの先頭に[Serializable]を追加します。

C。他の問題がある場合は、jsonが有効であることを確認してください。このサイトに移動します here にjsonを貼り付けます。 JSONが有効かどうかが表示されます。また、Jsonを使用して適切なクラスを生成する必要があります。必ず、各変数からremove{ get; set; }を削除し、生成された各クラスの先頭に[Serializable]を追加してください。


Newtonsoft.Json:

何らかの理由Newtonsoft.Jsonを使用する必要がある場合は、Unityの分岐バージョンを確認してください here 。特定の機能を使用するとクラッシュする可能性があることに注意してください。注意してください。


質問に回答するには

元のデータは

 [{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]

Add{"Items": infrontthen thenadd}end).

これを行うコード:

serviceData = "{\"Items\":" + serviceData + "}";

今、あなたは持っています:

 {"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}

serializeに、PHPからのmultipleデータをarrays、今すぐできる

public player[] playerInstance;
playerInstance = JsonHelper.FromJson<player>(serviceData);

playerInstance[0]は最初のデータです

playerInstance[1]は2番目のデータです

playerInstance[2]は3番目のデータです

またはplayerInstance[0].playerLocplayerInstance[1].playerLocplayerInstance[2].playerLocを含むクラス内のデータ......

playerInstance.Lengthを使用して、アクセスする前に長さを確認できます。

注:Removeplayerクラスから{ get; set; }{ get; set; }がある場合、動作しません。 UnityのJsonUtilityは、ではなくではなく、properties

179
Programmer

このようなJSONを手に入れたとしましょう。

[
    {
        "type": "qrcode",
        "symbol": [
            {
                "seq": 0,
                "data": "HelloWorld9887725216",
                "error": null
            }
        ]
    }
]

上記のJSONを統一して解析するには、このようにJSONモデルを作成します。

[System.Serializable]
public class QrCodeResult
{
    public QRCodeData[] result;
}

[System.Serializable]
public class Symbol
{
    public int seq;
    public string data;
    public string error;
}

[System.Serializable]
public class QRCodeData
{
    public string type;
    public Symbol[] symbol;
}

そして、次のように単純にパースします。

var myObject = JsonUtility.FromJson<QrCodeResult>("{\"result\":" + jsonString.ToString() + "}");

必要に応じてJSON/CODEを変更することができます。 https://docs.unity3d.com/Manual/JSONSerialization.html

11
Narottam Goyal

このように、PlayerItemクラスに[System.Serializable]を追加する必要があります。

using System;
[System.Serializable]
public class PlayerItem   {
    public string playerId;
    public string playerLoc;
    public string playerNick;
}
1
Myan

JSONファイルを読むには、この簡単な例を参照してください。

あなたのJSONファイル(StreamingAssets/Player.json)

{
    "Name": "MyName",
    "Level": 4
}

C#スクリプト

public class Demo
{
    public void ReadJSON()
    {
        string path = Application.streamingAssetsPath + "/Player.json";
        string JSONString = File.ReadAllText(path);
        Player player = JsonUtility.FromJson<Player>(JSONString);
        Debug.Log(player.Name);
    }
}

[System.Serializable]
public class Player
{
    public string Name;
    public int Level;
}
0

@Maximiliangerhardtが言ったように、MiniJsonには正しくデシリアライズする機能がありません。私はJsonFxを使っていて魅力のように働きます。 []で動作します

player[] p = JsonReader.Deserialize<player[]>(serviceData);
Debug.Log(p[0].playerId +" "+ p[0].playerLoc+"--"+ p[1].playerId + " " + p[1].playerLoc+"--"+ p[2].playerId + " " + p[2].playerLoc);
0
dil33pm

[]をトリミングしないでください。そうすれば大丈夫です。 []はJSON配列を識別します。これはまさにその要素を反復できるようにするために必要なものです。

0
Thomas Hilbert