【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";
}
}
