Android環境では、SteamingAssetsのパスがURIで表されます。
具体的には「jar:file://data/app/xxxxxxx/base!.apk/assets/ファイル名」などになります。
UnityのAndroidってStreamingAssetsがURIになるの知らなかった。。ifディレクティブで書き分けないとか。 pic.twitter.com/aDnV66jFSZ
— とりカシュ (@torikasyu) January 29, 2022
なので、他のプラットフォームのようにファイルシステムとしてFileクラスやStreamReaderクラスでアクセスすることはできず、UnityWebRequestなどを使うことになります。
そうすると他のプラットフォームやUnityEditorで動作しなくなるので、パスがURIかどうかをチェックして場合分けをしてみました。
Uri.IsWellFormedUriString
を使用すると、URIかどうかがチェックできるので、それに応じてアクセス方法を変えています。
SteamingAssets直下に置いたjpgファイルをテクスチャとして表示するサンプルです。
(テクスチャ以外のデータも扱えるように、UnityWebRequestTextureは使用していません)
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; using System.IO; using UnityEngine.Networking; using UnityEngine.UI; public class MyScript : MonoBehaviour { [SerializeField] Text logText; [SerializeField] RawImage image; public void Start() { var path = Path.Combine(Application.streamingAssetsPath, "fuji.jpg"); logText.text = path; StartCoroutine(AssetLoader(path, FinishAction)); } void FinishAction(byte[] bytes) { logText.text += $"\n[{bytes.Length}]"; Texture2D texture = new Texture2D(1, 1); texture.LoadRawTextureData(bytes); texture.LoadImage(bytes); image.texture = texture; } IEnumerator AssetLoader(string filePath, Action<byte[]> finishAction) { bool isURI = Uri.IsWellFormedUriString(filePath, UriKind.Absolute); byte[] data = { }; if (isURI) { var request = UnityWebRequest.Get(filePath); yield return request.SendWebRequest(); if (request.result == UnityWebRequest.Result.Success) { data = request.downloadHandler.data; } else { logText.text += $"\n{request.error}"; yield break; } } else { try { data = File.ReadAllBytes(filePath); } catch(Exception ex) { logText.text += $"\n{ex.Message}"; yield break; } } finishAction?.Invoke(data); } }