- Home /
Unity can read Json file, but Android not.
My json works on Unity, but when I try to build to Android, I can't load any questions. here is my code, I can't understand what it's going wrong.
using System.Collections; using System.Collections.Generic; using UnityEngine; using System.IO; using UnityEngine.UI; using UnityEngine.Networking; using UnityEngine.SceneManagement;
public class QuestionManager : MonoBehaviour {
public Text debugLog;
public ShowToast androidOutput;
public Text pregunta;
public Button r1;
public Button r2;
public Button r3;
public Button r4;
public Text textoTiempoRestante; //Texto donde se muestra el tiempo que te queda
public int q = 1; // 1-25 Varaible entera que sera el numero de la pregunta actual
public static int Length = 25; // 1-25 Variable entera define el numero total de preguntas
public Text textScore; //El texto lo aplicamos al Score de la UI
public static int score; //= 0;
private QuestionCategories m_categories; // Donde se almacenan la categorías
private float tiempoRestante = 15f; //Tiempo para contestar la pregunta
void Update() //Se ejecuta cada frame
{
textScore.text = "Score: " + score;
tiempoRestante -= Time.deltaTime; //Restame del tiempo, un segundo cada segundo.
textoTiempoRestante.text = "" + System.Math.Round(tiempoRestante, 1); //Escribeme en la pantalla, el tiempo que me queda. Y le digo que solo me muestre un decimal.
if(tiempoRestante < 0) //Si el tiempo es inferior a 0, ejecutame el siguiente codigo.
{
Debug.Log("¡Tiempo agotado!"); //Si se acaba el tiempo, sale ese mensaje en la consola de UNITY unicamente.
androidOutput.showToastOnUiThread("¡Tiempo agotado!"); //Si se acaba el tiempo, sale ese mensaje en el telefono móvil.
if (Length < q) // si q es mes gran que Length significa que no hay mas preguntas
{
SceneManager.LoadScene("Ranking"); // en este caso cambia la escena a Ranking
}
LoadQuestion(); //Cargame una pregunta nueva.
tiempoRestante = 15f; //Añademe 15s al tiempo restante para la siguiente pregunta.
}
}
private void Awake() // Se ejecuta al empezar el juego
{
//Chequea o comprueba las respuestas al pulsar
r1.onClick.AddListener(delegate {CheckAnswer(r1); });
r2.onClick.AddListener(delegate {CheckAnswer(r2); });
r3.onClick.AddListener(delegate {CheckAnswer(r3); });
r4.onClick.AddListener(delegate {CheckAnswer(r4); });
// Per validar els vostres JSON si son correctes: https://jsonformatter.curiousconcept.com/
ReadFile("SampleQuestions.json"); // Esto lee el archivo de las preguntas (json)
}
// COSAS NASIS DE ANDROID TETE
private void ReadFile(string fileName)
{
// Explicació del que son els StreamingAssets: https://docs.unity3d.com/Manual/StreamingAssets.html
string filePath;
// Explicació del que es el PlatformDependentCompilation: https://docs.unity3d.com/Manual/PlatformDependentCompilation.html
#if UNITY_EDITOR
filePath = Path.Combine(Application.dataPath + "/StreamingAssets", fileName);
MostrarLog(filePath);
if(File.Exists(filePath))
{
string dataAsJson = File.ReadAllText(filePath);
m_categories = JsonUtility.FromJson<QuestionCategories>(dataAsJson);
LoadQuestion();
}
else
{
MostrarLog("Cannot load game data!");
}
#elif UNITY_ANDROID
filePath = Path.Combine("jar:file://" + Application.dataPath + "!/assets/", fileName);
StartCoroutine(LoadAndroidFile(filePath));
#endif
}
IEnumerator LoadAndroidFile(string filePath)
{
// Explicació del que son les Coroutines: https://unity3d.com/es/learn/tutorials/topics/scripting/coroutines?playlist=17117
// Explicació del que es la classe WWW: https://docs.unity3d.com/ScriptReference/WWW.html
WWW loadFileRequest = new WWW(filePath);
yield return loadFileRequest;
string dataAsJson = loadFileRequest.text;
MostrarLog(dataAsJson);
m_categories = JsonUtility.FromJson<QuestionCategories>(dataAsJson);
LoadQuestion();
}
Answer by Legend_Bacon · Nov 27, 2018 at 06:07 PM
Hello there,
You may want to debug the Path you are using on android (make a text somewhere on screen, and feed it the path you are using).
I don't think you need the Path.Combine() call... Here is an example of some of my working code:
path = "jar:file://" + Application.dataPath + "!/assets/version.json"
I hope that helps!
Cheers
~LegendBacon
Note that the strea$$anonymous$$g assets for android are packed inside the AP$$anonymous$$ file and can not be accessed directly through file IO. Unity's WWW class recognises this special URL scheme (jar:) and do some zip magic behind the scenes to load a file from inside the AP$$anonymous$$. I recommend to have a look at the last paragraph of the Strea$$anonymous$$gAssets documentation
ps: Another common reason for things that work on windows and doesn't work on android is case sensitivity of file and pathnames. On windows file and pathnames are case insensitive. So "C:\$$anonymous$$yFolder\SomeFile.txt "
is the same as "C:\mYfOLDER\sOmEfiLe.txT "
. Since Android is a linux based system, file and path names are case sensitive. So the casing of the names have to match exactly. This is also a common issue when setting up a website on a local hosted windows server and then moving onto an actual webserver which in 99% of all cases run on linux.
Answer by mguidry · Nov 27, 2018 at 06:44 PM
I am pretty sure you have to use Application.persistentDataPath instead of Application.dataPath for Android platform.