9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

HoloLensでFilepickerから選択したVRMファイルを読み込む

Last updated at Posted at 2018-09-13

はじめに

HoloLensでVRMファイルを読み込んで表示してみました。
VRMファイルはFilePickerを使ってフォルダから選択できるようにしました。

サンプルプロジェクトこちら ⇒ VRMRuntimeLoaderSampleForHoloLens

いくつかハマりどころがありましたが、ポイントは以下の2点です。

  • Player SettingsのScripting BackendをIL2CPPに設定する。
  • IL2CPPビルドでファイルを読み込む時はWWWクラスを使う。
    (WWWクラスを使わないとDirectoryNotFoundExceptionが発生する)

VRMHoloLens01.jpg
VRMHoloLens02.jpg

開発・検証環境

  • UniVRM v0.43
  • Unity 2017.4.9f1
  • Visual Studio 2017
  • HoloLens RS5 Preview (OS Build: 17720.1000)

事前準備・設定

UniVRMのインポート

UniVRM v0.43のunitypackageをダウンロードしてインポートする。
UniVRM.png

IL2CPPビルドの設定

Player Settings/Other SettingsのScripting BackendをIL2CPPに設定する。
IL2CPP.png

Capabilitiesの設定

VRMファイルが置いてあるフォルダにアクセスできるようにCapabilitiesを設定する。
今回はObjects3Dフォルダを使うため、Player Settings/Publishing Settings/CapabilitiesのObjects3Dにチェックを入れておく。
Capabilities.png

VRMファイルを選択してランタイムロードする

サンプルスクリプト

以下のようなスクリプトを空のゲームオブジェクトにアタッチします。

VRMRuntimeLoaderUsingFilePicker.cs
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);
		}
	}

参考情報

9
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?