Hello, everyone. Now I’m trying to implement localization in my small project by learning from Unity Live Training.
Unity Live Training:
It works fine in editor, but when I build and test run on an Android device, it can’t find the right path and replace the text with the localized one. I researched a lot on the internet and tried to fix it by myself, but sadly it didn’t work. (I have 0 experience on json and streaming assets.) The following is the script in my project. I’m really not sure how to fix it. I’ll appreciate it if anyone could help me. Thank you.
You shouldn’t have to add /Raw and jar://file:// to streamingassetspath, it should already include that. (thus the purpose of using streamingassetspath)
You may even consider putting your json in the Resource folder instead, as this will allow you to read the file with ReadAllText no matter what platform you are on. (just a suggestion, but the above should fix your issue)
Edit: Correction on this. ReadAllText should be used for the persistantDataPath. Resources would use Resources.Load and load it in as a TextAsset (to which you can toString to get the json string out of).
You can use log viewer on the asset store (free) https://www.assetstore.unity3d.com/en/#!/content/12047 to view your console on a device. Print out what application.streamingassetspath shows (this will also allow you to see your debugs quickly)
Hello !
Did you solve the problem ? Because I’m trying to do it, but I don’t really succeed.
And I have one more question. Is anyone can help to make a save function of this code?
Thank you
System.IO classes can read files on a file system. StreamingAssets on Android is a directory inside APK, which is a zip file. System.IO classes can’t read files from inside zip.
UnityWebRequest and WWW can do that.
Hi this is not working for me as well. Can someone pls tell me what is the final solution they got working? I’m trying to get this to work for Android and WebGL.
Hello,
Thanks for the reply. UnityWebRequest seems to be working partially on WebGL(it removes special characters on WebGL but shows all fine in unity game editor?). But its not working on Android. I tried printing the file path and its actually showing correct file path even then its not able to read it? Please take a look at the code below
So, I did a quick test to make sure I wasn’t crazy and had no issues. The text printed out from the text file just fine.
Note a couple of things I did. I used the UNITY_ANDROID platform dependent tags located here Unity - Manual: Conditional compilation
A better option for you vs checking the filepath itself.
The other thing I did was use log viewer located here Log Viewer | Integration | Unity Asset Store
Note it’s a bit outdated and will yell at you about a line in the code that references unity webplayer, but you can just delete the line and save the script and it will be fine. You can bring up log viewer on the android device to see errors, debug/print calls, and some other info.
I know this is a bit old, but I wanted to post my code too. It’s working on android, ios and win-editor, Unity 2019.4. After reading Json string, I use JsonUtility.FromJson.
Error checking may be implemented by: if (www.isNetworkError || www.isHttpError).
Btw, code is not in an IEnumerator so loading happens in one frame. This is the reason using while (!www.isDone) ;
Triple_Why you sir are a life saver, I have been going around in circles for the last 48 hours trying to figure out why a JSON file is happily being read in the Editor but fails when I throw it into the Build and run it on my test Android device. Because of your code above, I can now read the JSON file.
triple_why
Thank you very much for the piece of code, that you have posted, you have also helped me too much I have been looking for this Answer and this is the one that works 100% … I can only say! I recommend this code. Thank you very much
Hi! I’m quite new to Unity’s webrequest and json. In my game I have a .json file, which contains data about what skins player has. Since I’m using (Application.streamingAssetsPath + “/Skins.json”) as my path, it doesn’t work in Android so I tried to use your code. My question is: where should I put your code? In the start method OR create a new coroutine and run it in the start method OR just simply put your method into my LoadData/SaveData methods?
public void LoadData(){
skins = JsonUtility.FromJson<Skins>(File.ReadAllText(Application.streamingAssetsPath + "/SaveSkins.json"));
}
public void SaveData(){
File.WriteAllText(Application.streamingAssetsPath + "/SaveSkins.json", JsonUtility.ToJson(skins));
}
[System.Serializable]
public class Skins{
public bool[] isPurchased;
}
}
Hi! The code I posted is not in an IEnumerator, making it synchronous, so loading happens in one frame. Meaning being in a coroutine or in Start() is ok, but is not necessary. I would load&save when needed, i.e. in your LoadData/SaveData methods.
But, I was merely loading files by my code. For saving, you cannot use StreamingAssets folder, have to use persistentDataPath. For clarification;
Application.streamingAssetsPath: Filled with files/folders from StreamingAssets folder at compile time, cannot be changed at runtime. Files/folders in this location can be changed only by app updates. This folder and subfolders are read-only. Multiplatform reading (excluding WebGL) can be done by the code I’ve posted.
Application.persistentDataPath: Empty folder by default. Can be populated by files/folders at first launch of the app or at any runtime. Files/folders in this location are not erased by app updates. This folder and subfolders are readable/writable. Multiplatform reading/writing (including WebGL) can be done by using File and Directory classes from System.IO namespace.
Thank you for replying! Firstly, could you please check my code below, where I tried to implement your UnityWebRequest code into my Load/Save data methods. I guess I did something incorrectly, because now my “SaveSkins.json”'s structure doesn’t change at all(before it was switching isPurchased boolean from false to true).
Before:
public void LoadData(){
skins = JsonUtility.FromJson<Skins>(File.ReadAllText(Application.streamingAssetsPath + "/SaveSkins.json"));
}
public void SaveData(){
File.WriteAllText(Application.streamingAssetsPath + "/SaveSkins.json", JsonUtility.ToJson(skins));
}
After:
public Skins skins;
public void LoadData(){
string sFilePath = Path.Combine(Application.streamingAssetsPath, "SaveSkins.json");
string sJson;
if (Application.platform == RuntimePlatform.Android)
{
UnityWebRequest www = UnityWebRequest.Get(sFilePath);
www.SendWebRequest();
while (!www.isDone) ;
sJson = www.downloadHandler.text;
skins = JsonUtility.FromJson<Skins>(File.ReadAllText(sJson));
}
else sJson = File.ReadAllText(sFilePath);
}
public void SaveData(){
string sFilePath = Path.Combine(Application.streamingAssetsPath, "SaveSkins.json");
string sJson;
if (Application.platform == RuntimePlatform.Android)
{
UnityWebRequest www = UnityWebRequest.Get(sFilePath);
www.SendWebRequest();
while (!www.isDone) ;
sJson = www.downloadHandler.text;
File.WriteAllText(sJson, JsonUtility.ToJson(skins));
}
else sJson = File.ReadAllText(sFilePath);
}
[System.Serializable]
public class Skins{
public bool[] isPurchased;
}
Secondly, you suggested me to use Application.persistentDataPath for saving. The problem is I am a newbie in using file-related things, so I simply don’t know how to create a json file inside persistentDataPath folder with the values from my SaveSkins.json file. Also, how should I detect if it’s the very first launch of the game or not? On the web I found info that it could be done by using PlayerPrefs when player first enters the game and set PlayerPrefs.SetInt(“firstLaunch”, 1).
Would be great if you could help me with that(I’m already learning from the links you posted in your previous reply, so thank you for that as well!)