[解決済み] UnityでJsonとJson Arrayをシリアライズ/デシリアライズする
質問
PHPファイルからunityに送信されるアイテムのリストを
WWW
.
は
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));
}
ありがとうございます。
どのように解決するのですか?
Unityを追加しました。 JsonUtility を API に追加しました。 5.3.3 更新しました。もっと複雑なことをしない限り、すべてのサードパーティライブラリのことは忘れてください。JsonUtilityは他のJsonライブラリより高速です。Unityへのアップデート 5.3.3 バージョン以上にしてから、以下の解決策を試してみてください。
JsonUtility
は軽量なAPIです。単純な型のみをサポートしています。これは
ではなく
はDictionaryのようなコレクションをサポートしません。一つの例外は
List
. これは
List
と
List
の配列になります!
をシリアライズする必要がある場合
Dictionary
をシリアライズする必要がある場合、または単純なデータ型のシリアライズとデシリアライズ以外のことを行う場合は、サードパーティのAPIを使用してください。それ以外の場合は、読み進めてください。
シリアライズするクラスの例です。
[Serializable]
public class Player
{
public string playerId;
public string playerLoc;
public string playerNick;
}
1. 1つのデータオブジェクト(非配列のjson)
シリアライズ そのA :
シリアライズ
をJsonに変換するために
public static string ToJson(object obj);
メソッドでJsonに変換します。
Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";
//Convert to JSON
string playerToJson = JsonUtility.ToJson(playerInstance);
Debug.Log(playerToJson);
出力 :
{"playerId":"8484239823","playerLoc":"Powai","playerNick":"Random Nick"}
連載パートB :
シリアライズ
をJsonに変換するために
public static string ToJson(object obj, bool prettyPrint);
メソッドのオーバーロードです。単に渡すだけで
true
を
JsonUtility.ToJson
関数がデータをフォーマットします。下の出力と上の出力を比べてみてください。
Player playerInstance = new Player();
playerInstance.playerId = "8484239823";
playerInstance.playerLoc = "Powai";
playerInstance.playerNick = "Random Nick";
//Convert to JSON
string playerToJson = JsonUtility.ToJson(playerInstance, true);
Debug.Log(playerToJson);
出力 :
{
"playerId": "8484239823",
"playerLoc": "Powai",
"playerNick": "Random Nick"
}
デシリアライズ そのA :
デシリアライズ
というjsonを
public static T FromJson(string json);
メソッドをオーバーロードします。
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = JsonUtility.FromJson<Player>(jsonString);
Debug.Log(player.playerLoc);
デシリアライズ そのB :
デシリアライズ
というjsonを
public static object FromJson(string json, Type type);
メソッドをオーバーロードします。
string jsonString = "{\"playerId\":\"8484239823\",\"playerLoc\":\"Powai\",\"playerNick\":\"Random Nick\"}";
Player player = (Player)JsonUtility.FromJson(jsonString, typeof(Player));
Debug.Log(player.playerLoc);
デシリアライズ そのC :
デシリアライズ
というjsonを
public static void FromJsonOverwrite(string json, object objectToOverwrite);
メソッドを使用します。いつ
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. 複数データ(配列json)
あなたのJsonは複数のデータオブジェクトを含んでいます。例えば
playerId
よりも多く出現し
が一度だけ
. ユニティの
JsonUtility
はまだ新しいので配列はサポートしていませんが、このような場合は
ヘルパー
クラスを使って
配列
と連携して
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 JSON
string playerToJson = JsonHelper.ToJson(playerInstance, true);
Debug.Log(playerToJson);
出力 :
{
"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);
出力 :
ポワイ
ユーザー2
もしこれがサーバからの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" プロパティが数字で始まるため、これをサポートしません。クラス変数が整数で始まることはありません。
ダウンロード
SimpleJSON.cs
をUnityの
ウィキ
.
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.TROUBLESHOOTING JsonUtility:
でシリアライズする際の問題
JsonUtility.ToJson
?
空文字列または " を取得します。
{}
というように
JsonUtility.ToJson
?
A
. クラスが配列でないことを確認してください。もしそうなら、上記のヘルパークラスで
JsonHelper.ToJson
の代わりに
JsonUtility.ToJson
.
B
. 追加
[Serializable]
をシリアライズするクラスの先頭に追加してください。
C
. クラスからプロパティを削除します。例えば、変数に
public string playerId { get; set; }
を削除します。
{ get; set; }
. Unityはこれをシリアライズすることができません。
でデシリアライズした場合の問題
JsonUtility.FromJson
?
A
. もし、あなたが
Null
が表示された場合、JsonがJson配列でないことを確認してください。もしそうなら、上記のヘルパークラスで
JsonHelper.FromJson
の代わりに
JsonUtility.FromJson
.
B
. もし、あなたが
NullReferenceException
が表示された場合、デシリアライズ中に
[Serializable]
をクラスの先頭に追加します。
C
.その他の問題がある場合は、jsonが有効であることを確認してください。このサイトへ
こちら
にアクセスし、jsonを貼り付けてください。jsonが有効かどうかが表示されるはずです。また、Jsonと一緒に適切なクラスが生成されるはずです。ただ、必ず
を削除してください。
{ get; set; }
を各変数から削除し、さらに
[Serializable]
を生成された各クラスの先頭に追加してください。
Newtonsoft.Json。
もし何らかの理由で Newtonsoft.Json を使用しなければならない場合は、Unity用にフォークされたバージョンをチェックアウトしてください。 ここで . なお、特定の機能を使用するとクラッシュすることがあります。ご注意ください。
ご質問にお答えします。 :
あなたの元データは
[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]
追加
{"Items":
で
フロント
であれば、それの
加える
}
で
末尾
を追加してください。
これを行うためのコードです。
serviceData = "{\"Items\":" + serviceData + "}";
これで
{"Items":[{"playerId":"1","playerLoc":"Powai"},{"playerId":"2","playerLoc":"Andheri"},{"playerId":"3","playerLoc":"Churchgate"}]}
への シリアライズ は 複数の のデータを php から 配列 であれば、これで
public player[] playerInstance;
playerInstance = JsonHelper.FromJson<player>(serviceData);
playerInstance[0]
が最初のデータです。
playerInstance[1]
は2番目のデータです。
playerInstance[2]
は3番目のデータです。
またはクラス内のデータで
playerInstance[0].playerLoc
,
playerInstance[1].playerLoc
,
playerInstance[2].playerLoc
......
を使うことができます。
playerInstance.Length
を使って、アクセスする前に長さをチェックすることができます。
注意
を削除する
{ get; set; }
を削除します。
player
クラスと同じです。もし
{ get; set; }
を指定した場合、動作しません。Unityの
JsonUtility
は
ではない
として定義されているクラスのメンバで動作します。
プロパティ
.
関連
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】クロススレッド操作が有効でない。作成されたスレッド以外のスレッドからアクセスされたコントロール
-
[解決済み] 正しいJSONコンテンツタイプは何ですか?
-
[解決済み] JSONでコメントを使用することはできますか?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] なぜGoogleはJSONレスポンスにwhile(1);を前置するのでしょうか?
-
[解決済み] cURLでJSONデータをPOSTするにはどうすればよいですか?
-
[解決済み] JavaScriptでJSONをきれいに印刷する
-
[解決済み] JSONをC#のダイナミックオブジェクトにデシリアライズする?
-
[解決済み] ASP.NETでJSONを単純なDictionary<string,string>にデシリアライズするにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み】「入力文字列が正しい形式ではありませんでした」エラーの解決方法は?[重複しています]。
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】MetadataException: 指定されたメタデータ・リソースをロードできない
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】"指定されたパスのフォーマットはサポートされていません。"
-
[解決済み】値をNULLにすることはできません。パラメータ名:source
-
[解決済み】2年前のMSDateを把握する【クローズド
-
[解決済み】ファイルやアセンブリ、またはその依存関係の1つをロードできませんでした。
-
VSでscanfエラーを恒久的に解決するには、ソースファイルを作成し、自動的に#define _CRT_SECURE_NO_WARNINGS 1を追加してください。