【Unity】Android版でStreamingAssetsにあるglTF形式のファイルをTriLib2で開きたい場合
ちょっと時間かかったのでメモがてらに書いておきます。
ランタイム版でもFBX、OBJ、glTF形式をロードできるようになる有償アセット「TriLib2」ですが、Assets/StreamingAssetsディレクトリ以下に保管してあるglTF形式の3Dデータファイルを読み込みたいのですが、Android版だけうまく行かない。Windows版とiOS版は問題なかった。
UnityWebRequestを噛ます必要がありました。
using System.IO; using System.Collections; using UnityEngine; using UnityEngine.UI; using System; using UnityEngine.Networking; using TriLibCore; /// <summary> /// Android版でStreamingAssetsのGLBファイルをTriLib2を使って読み込むためのサンプル /// 手順: /// 1. パスを生成して、UnityWebRequestでバイナリデータdataを取得する /// 2. dataをstreamに変換して、LoadModelFromStream関数に渡す /// </summary> public class GltfLoader1 : MonoBehaviour { Text _t = null; GameObject _wrapperGameObject = null; // Start is called before the first frame update void Start() { _wrapperGameObject = GameObject.Find("obj1"); _t = GameObject.Find("Text1").GetComponent<Text>(); #if UNITY_ANDROID && !UNITY_EDITOR string path = Path.Combine(Application.streamingAssetsPath, "gltf", "workerman.glb"); #else string path = Path.Combine(Application.streamingAssetsPath, "gltf", "workerman.glb"); #endif DebugLog("### path: " + path); #if UNITY_ANDROID && !UNITY_EDITOR StartCoroutine(AssetLoad(path, OnFinish)); #else AssetLoader.LoadModelFromFileNoThread(path, OnError, _wrapperGameObject, null, null); #endif } /// <summary> /// リクエストを飛ばす /// </summary> /// <param name="filePath"></param> /// <param name="finish"></param> /// <returns></returns> IEnumerator AssetLoad(string filePath, Action<string, byte[]> onFinish) { byte[] data = { }; var request = UnityWebRequest.Get(filePath); DebugLog("### Send Web Request"); yield return request.SendWebRequest(); if (request.isDone) { DebugLog("### request.isDone"); data = request.downloadHandler.data; } else { DebugLog("### request error"); yield break; } onFinish?.Invoke(filePath, data); } void OnFinish(string filePath, byte[] bytes) { DebugLog($"### bytes= [{bytes.Length}]"); if (bytes.Length == 0) return; string file = System.IO.Path.GetFileName(filePath); Stream stream = new MemoryStream(bytes); // 同期的に //AssetLoader.LoadModelFromStreamNoThread(stream, file, null, OnError, _wrapperGameObject); // 非同期で AssetLoader.LoadModelFromStream(stream, file, null, OnLoad, OnMaterialsLoad, null, OnError, _wrapperGameObject); } void OnLoad(AssetLoaderContext assetLoaderContext) { DebugLog("OnLoad!"); } void OnMaterialsLoad(AssetLoaderContext assetLoaderContext) { DebugLog("OnMaterialsLoad!"); } void OnError(IContextualizedError error) { DebugLog("OnError!: " + error.GetInnerException().Message); } void DebugLog(string msg) { Debug.Log(msg); _t.text += msg; _t.text += " \r\n"; } }