Read and Write File on Streamingassetspath

Writing to Unity's StreamingAssets folder at runtime, on Android?

The project assests (StreamingAssets ,RawAssets,etc..) are read only, you cant write anything there, instead write write to internal/external storage have a look here, if you prefer writing in c# i believe that you would use Xaramin framework

Read/Load image file from the StreamingAssets folder

While reading files in the StreamingAssets folder, you have to use WWW on some platforms or File.ReadAllBytes some others. You check if the path contains :// or :/// then determine which one to use. This should solve the question mark issue. Note that you should now be using UnityWebRequest where WWW is required unless there is a bug with UnityWebRequest.


Another issue that will arise is the SpriteRenderer image not being upadte. The material will reflect the images changes but the SpriteRenderer will not. The proper way to change a sprite of a SpriteRenderer is to change the SpriteRenderer.sprite property. This means that you will have to Convert the Texture2D to Sprite then assign that sprite to the SpriteRenderer.sprite property.

Finally, use Application.streamingAssetsPath when accessing files in the StreamingAssets folder. This is not the issue now since you're running it in the Editor but will be in a build.

Below is what your code for reading image file in the StreamingAssets should look like:

using UnityEngine.Networking;

public string url;

IEnumerator Start()
{
///url = Application.dataPath + "/StreamingAssets/shareImage.png";
url = Path.Combine(Application.streamingAssetsPath, "shareImage.png");

byte[] imgData;
Texture2D tex = new Texture2D(2, 2);

//Check if we should use UnityWebRequest or File.ReadAllBytes
if (url.Contains("://") || url.Contains(":///"))
{
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
imgData = www.downloadHandler.data;
}
else
{
imgData = File.ReadAllBytes(url);
}
Debug.Log(imgData.Length);

//Load raw Data into Texture2D
tex.LoadImage(imgData);

//Convert Texture2D to Sprite
Vector2 pivot = new Vector2(0.5f, 0.5f);
Sprite sprite = Sprite.Create(tex, new Rect(0.0f, 0.0f, tex.width, tex.height), pivot, 100.0f);

//Apply Sprite to SpriteRenderer
SpriteRenderer renderer = GetComponent<SpriteRenderer>();
renderer.sprite = sprite;
}

Read json file from SreamingAssets folder

The fix is to load the contents, the call requires JSON text, not a file path:

ShipTypes shipTypes;
string path = Application.streamingAssetsPath + "/ShipTypes.json";
string contents = File.ReadAllText(path);
shipTypes = JsonUtility.FromJson<ShipTypes>(contents);

How read json from Unity StreamingAssets, Android

Based on this Manual:

On Android, the files are contained within a compressed .jar file (which is essentially the same format as standard zip-compressed files). This means that if you do not use Unity’s WWW class to retrieve the file, you need to use additional software to see inside the .jar archive and obtain the file.

public void ReadJson(){
string path = Application.streamingAssetsPath + "/elements.json";
#if UNITY_EDITOR
path = "/StreamingAssets/elements.json";
#endif
WWW www = new WWW(path);
while(!www.isDone) {}
string json = www.text;
itemsContent = JsonUtility.FromJson<Main> (json);
bundleForPing = itemsContent.bundleID;
}

Unity Android's StreamingAssets folder location

You can not add or modify files that are inside the streaming assets folder after building since on almost all platforms the directory is read only. From the docs:

On many platforms, the streaming assets folder location is read-only; you can not modify or write new files there at runtime. Use Application.persistentDataPath for a folder location that is writable.

That said, on Android the filepath to the streaming assets is at "jar:file://" + Application.dataPath + "!/assets, from the same docs:

Android uses files inside a compressed APK
/JAR file, "jar:file://" + Application.dataPath + "!/assets".

Do note that you can not access this file location through the standard C# File functions, but need to access it using a webrequest.

If you need a directory to store data during run time you need to use the Application.persistenDataPath instead.
From the docs:

This value is a directory path where you can store data that you want to be kept between runs. When you publish on iOS and Android, persistentDataPath points to a public directory on the device. Files in this location are not erased by app updates. The files can still be erased by users directly.

File read/write paradigms on Unity- which to use?

You can get a basic idea in this answer.

In addition, I would suggest placing anything you want to package with your game in your Resources folder, which you can access by using Resources.Load(). You can iterate through these directories however you want- ex: Resources.Load("folder/file");.

If you want to write files, they have to go in Application.persistentDataPath as that's the only write-able directory (that's specified by Unity), i.e. for run-time files only. But once a file is stored there, it is persistent between sessions.

You can, of course, specify absolute paths and try to load assets from there, but that's more risk than necessary (paths differ on different devices).
You could ignore Application.dataPath altogether, until you find a specific need for it (ex: to access files that are not in persistentDataPath, but not in resources either).

I hope that helps!



Related Topics



Leave a reply



Submit