Unity : Json

Kaos

Buenas a todos! Tenía una consultita para los pro's de Unity. Estoy empezando con Unity, y estoy dándole caña a prácticas orientadas a crear un juego de cartas. Las cartas las quiero recibir de un JSON. He bajado la versión 5.3 porque lleva un des-serializador de Json de serie (una de las novedades del 5.3). Tengo este código (Que funciona):

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ReadJson : MonoBehaviour {

IEnumerator Start() {

	WWW www = new WWW("https://dl.dropboxusercontent.com/u/271695/cartas.json");				
	yield return www;
	string json = www.text;

	Card NewCard = JsonUtility.FromJson<Card>(json);

	Debug.Log (NewCard.name);

}

[Serializable]
public class Card
{
	public int id;
	public string name;
	public string Description;
	public string Faction;
	public string Type;
	public string Rarity;
	public int AP;
	public int HP;
	public int CD;
}

}

El único "Problema" que tengo ahora es que quiero que el archivo Json lleve más de una carta (20 cartas llevará) y no sé cómo afrontarlo. ¿Alguna sugerencia? Me gustaría que cada una de las cartas estuviera en una dependencia de "Card". Card[0] - Card[1] o algo así, la verdad que no lo tengo muy claro. Qué me aconsejais?

A priori mi problema principal es leer varios elementos del archivo, en lugar de uno. En cuanto meto más de una carta peta el código (lógicamente).

¡Gracias!

r2d2rigo
List<Card> NewCards = JsonUtility.FromJson<List<Card>>(json);

Y que tu JSON tenga los datos metidos en un array: http://www.w3schools.com/json/json_syntax.asp

1 respuesta
Kaos

#2 Muchas gracias! Me temía que había que hacer una lista, sí, y no sé si llegaría a intentarlo pero el JSon me seguía dando error. He probado a meterlo en un array, tal que así:

"cards":[
    {"id": 0, "name": "Griffin Raider", "description": "A very fast unit!", "faction": "Imperial", "ap": 1, "hp": 3, "cd": 0, "type": "Magic", "rarity": "Common"},
    {"id": 1, "name": "Ghoul", "description": "Could you kill what you cant see?", "faction": "Inmortals", "ap": 3, "hp": 5, "cd": 4, "type": "Magic", "rarity": "Common"}
]

Y el código me sigue diciendo:

ArgumentException: JSON parse error: The document root must not follow by other values.
UnityEngine.JsonUtility.FromJson[List`1] (System.String json) (at C:/buildslave/unity/build/artifacts/generated/common/modules/JSONSerialize/JsonUtilityBindings.gen.cs:24)
ReadJson+<Start>c__Iterator0.MoveNext () (at Assets/Scripts/ReadJson.cs:14)
Kaos

En caso de dejar el JSON con este formato:

{
	"cards":[
		{"id": 0, "name": "Griffin Raider", "description": "A very fast unit!", "faction": "Imperial", "ap": 1, "hp": 3, "cd": 0, "type": "Magic", "rarity": "Common"},
		{"id": 1, "name": "Ghoul", "description": "Could you kill what you cant see?", "faction": "Inmortals", "ap": 3, "hp": 5, "cd": 4, "type": "Magic", "rarity": "Common"}
	]
}

No lanza ningún error, pero tampoco guarda ningún valor.

1 respuesta
r2d2rigo

#4 es que con ese JSON estas diciendo que tienes un objeto que contiene un campo "cards" que contiene un array, tienes que hacerlo asi:

[
                {"id": 0, "name": "Griffin Raider", "description": "A very fast unit!", "faction": "Imperial", "ap": 1, "hp": 3, "cd": 0, "type": "Magic", "rarity": "Common"},
                {"id": 1, "name": "Ghoul", "description": "Could you kill what you cant see?", "faction": "Inmortals", "ap": 3, "hp": 5, "cd": 4, "type": "Magic", "rarity": "Common"}
]

Para visualizar JSON esta herramienta te puede ser util: http://jsonviewer.stack.hu/

1 respuesta
Kaos

#5 jaja pues está la cosa complicada... con ese formato me da otro error:

"ArgumentException: JSON must represent an object type."

ArgumentException: JSON must represent an object type.
UnityEngine.JsonUtility.FromJson[List`1] (System.String json) (at C:/buildslave/unity/build/artifacts/generated/common/modules/JSONSerialize/JsonUtilityBindings.gen.cs:24)
ReadJson+<Start>c__Iterator0.MoveNext () (at Assets/Scripts/ReadJson.cs:14)

Que me parece que quiere decir que espera el nombre de un objeto delante del "["

Kaos

JODER SÍ!! Lo conseguí!! Dejo el código para los que lo necesiten, en Google no hay nada (supongo que por la relativa novedad de la 5.3 y el serializador).

El código queda tal que así:

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ReadJson : MonoBehaviour {

IEnumerator Start() {

	WWW www = new WWW("https://dl.dropboxusercontent.com/u/271695/cartas.json");
	yield return www;
	string json = www.text;

	Cards cartas = JsonUtility.FromJson<Cards>(json);
	Debug.Log (cartas.Cartas[0].name);

}

[System.Serializable]
public class Cards
{
	public List<Card> Cartas;
}

[System.Serializable]
public class Card
{
	public int id;
	public string name;
	public string description;
	public string faction;
	public string type;
	public string rarity;
	public int ap;
	public int hp;
	public int cd;
}

}

Y el JSON queda así:

{
	"Cartas":[
		{ "id": 0, "name": "Griffin Raider", "description": "A very fast unit!", "faction": "Imperial", "ap": 1, "hp": 3, "cd": 0, "type": "Magic", "rarity": "Common"},
		{ "id": 1, "name": "Ghoul", "description": "Could you kill what you cant see?", "faction": "Inmortals", "ap": 3, "hp": 5, "cd": 4, "type": "Magic", "rarity": "Common" }
	]
}
2
Kaos

Al final me he tenido que ceñir a la única estructura JSON que no le cantaba a Unity, cualquier otra configuración me petaba, no sé por qué. Pero bueno, esta estructura me viene bastante nice porque quería meter en un mismo JSON varias barajas.

Ty for the help r2d. De no ser por ti, no llego a la conclusión final. (O bueno, igual llego a mediados del 2016).

1 respuesta
r2d2rigo

#8 era la segunda sugerencia que te iba a hacer (clase root con campo para contener la lista), pero el que yo te puse anteriormente es un JSON valido, sera que el serializador de Unity es un ojete :|

En su momento use la libreria de Newtonsoft metida a pelo y funcionaba, aunque no se si dara problemas con el IL2CPP de Unity 5.

Kaos

Ieap, creo que es un tema de Unity5. O metes el JSON como quiere o te dan por el ojete