HoloLensでFilepickerから選択したVRMファイルを読み込む
はじめに
HoloLensでVRMファイルを読み込んで表示してみました。
VRMファイルはFilePickerを使ってフォルダから選択できるようにしました。
サンプルプロジェクトこちら ⇒ VRMRuntimeLoaderSampleForHoloLens
いくつかハマりどころがありましたが、ポイントは以下の2点です。
- Player SettingsのScripting BackendをIL2CPPに設定する。
- IL2CPPビルドでファイルを読み込む時はWWWクラスを使う。 (WWWクラスを使わないとDirectoryNotFoundExceptionが発生する)
開発・検証環境
- UniVRM v0.43
- Unity 2017.4.9f1
- Visual Studio 2017
- HoloLens RS5 Preview (OS Build: 17720.1000)
事前準備・設定
UniVRMのインポート
UniVRMのインポート
UniVRM v0.43のunitypackageをダウンロードしてインポートする。
IL2CPPビルドの設定
Player Settings/Other SettingsのScripting BackendをIL2CPPに設定する。
Capabilitiesの設定
VRMファイルが置いてあるフォルダにアクセスできるようにCapabilitiesを設定する。
今回はObjects3Dフォルダを使うため、Player Settings/Publishing Settings/CapabilitiesのObjects3Dにチェックを入れておく。
VRMファイルを選択してランタイムロードする
サンプルスクリプト
以下のようなスクリプトを空のゲームオブジェクトにアタッチします。
using System.Collections;
using UnityEngine;
using System.IO;
#if !UNITY_EDITOR && UNITY_WSA_10_0
using System;
using System.Threading.Tasks;
using Windows.Storage.Pickers;
#endif
public class VRMRuntimeLoaderUsingFilePicker : MonoBehaviour
{
public GameObject VRMRoot;
void Start ()
{
#if !UNITY_EDITOR && UNITY_WSA_10_0
UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
{
var openPicker = new FileOpenPicker();
openPicker.SuggestedStartLocation = PickerLocationId.Objects3D;
openPicker.FileTypeFilter.Add(".vrm");
var file = await openPicker.PickSingleFileAsync();
UnityEngine.WSA.Application.InvokeOnAppThread(() =>
{
if(file != null)
{
StartCoroutine(LoadVrmCoroutine(file.Path));
}
}, false);
}, false);
#elif UNITY_EDITOR
string path = Application.dataPath + "/Models/" + "default.vrm";
StartCoroutine(LoadVrmCoroutine(path));
#endif
}
IEnumerator LoadVrmCoroutine(string path)
{
var www = new WWW("file://" + path);
yield return www;
VRM.VRMImporter.LoadVrmAsync(www.bytes, OnLoaded);
}
void OnLoaded(GameObject vrm)
{
if(VRMRoot != null)
{
vrm.transform.SetParent(VRMRoot.transform, false);
}
}
}
ファイル選択
FileOpenPickerを使うことで、ファイルエクスプローラーを表示してファイルを選択することができます。
FileOpenPickerは、UnityのMainThreadでは利用できないため、UIThreadで動作させます。
選択されたファイルのパスをファイル読み込み用のメソッドに渡します。
"#if"の書き方はいくつかありますが、WINDOWS_UWPと書いてもIL2CPPで動くようです。
(参考:HoloLensのUnity内でFilepicker使ってみた)
#if !UNITY_EDITOR && UNITY_WSA_10_0
UnityEngine.WSA.Application.InvokeOnUIThread(async () =>
{
var openPicker = new FileOpenPicker();
openPicker.SuggestedStartLocation = PickerLocationId.Objects3D;
openPicker.FileTypeFilter.Add(".vrm");
var file = await openPicker.PickSingleFileAsync();
UnityEngine.WSA.Application.InvokeOnAppThread(() =>
{
if(file != null)
{
StartCoroutine(LoadVrmCoroutine(file.Path));
}
}, false);
}, false);
#elif UNITY_EDITOR
string path = Application.dataPath + "/Models/" + "default.vrm";
StartCoroutine(LoadVrmCoroutine(path));
#endif
VRMファイルの読み込み
WWWクラスでファイルを読み込み、byte配列をVRM.VRMImporter.LoadVrmAsyncに渡します。
IL2CPPビルドの場合、WWWクラスを使わないとDirectoryNotFoundExceptionが発生してファイルが読み込めませんでした。
また、VRMオブジェクトの位置や向きを調整できるように、OnLoadedメソッドでSetParentしています。
SetParentの第2引数(worldPositionStays)をfalseにしておくと調整可能です。(trueだとワールド座標系の位置・回転・スケールがキープされる)
IEnumerator LoadVrmCoroutine(string path)
{
var www = new WWW("file://" + path);
yield return www;
VRM.VRMImporter.LoadVrmAsync(www.bytes, OnLoaded);
}
void OnLoaded(GameObject vrm)
{
if(VRMRoot != null)
{
vrm.transform.SetParent(VRMRoot.transform, false);
}
}
参考情報
Author And Source
この問題について(HoloLensでFilepickerから選択したVRMファイルを読み込む), 我々は、より多くの情報をここで見つけました https://qiita.com/sotanmochi/items/83465078dea0be32be76著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .