はじめに
UnityでVRMファイルを読み込む2種類の方法をまとめました。
参考の記事を探してみても、半年前の記事がUniVRMのバージョンが上がり使えなくなっていたり、あまり参考にできなかったため、今の最新版のUniVRM(v0.98.0_2f6b
)でも使えるように備忘録程度に残しておきます。
※本投稿では、著作権等に配慮しスクショ等は載せておりません。
(初投稿なので誤字脱字等あるかもしれませんがご容赦ください。)
目次
- 事前準備
- ローカル上のファイル読み込み
- サーバー上のファイル読み込み
- まとめ
1. 事前準備
この記事を見られる方はUnityは既にインストールしてあるものとしてUnityのインストールの手順は割愛させて頂きます。
今回利用したUnityのバージョンは2021.3.1f1
です。4/13にUnity2021LTSがリリースされたため、早速使ってみました。
-
UniVRMの導入
-
UniVRMのリリースページから、4/30現在で最新のバージョン
UniVRM_Samples-0.98.0_2f6b.unitypackage
をダウンロードします。 - UnityEditorを開き、メニューバーの
Assets/Import Package/Custom Package...
を選択し、1.でダウンロードしたパッケージをインポートします。特に細かいこだわり等なければ何も考えずに全てインポートしてしまっていいと思います。※今回私も何も考えずに全てインポートしました。
-
UniVRMのリリースページから、4/30現在で最新のバージョン
-
UniTaskの導入
※スキップ可。await/asyncを使いたいって方はこちらを参考にしてください。本投稿ではawait/asyncを使っていますが、Unityのコルーチンで行っても問題ありません。
1. UniTaskのリリースページから、最新のバージョンUniTask.2.3.1.unitypackage
をダウンロードします。
2. UnityEditorを開き、メニューバーのAssets/Import Package/Custom Package...
を選択し、1.でダウンロードしたパッケージをインポートします。 -
VRMファイルの用意
こちら、読み込みができているかどうかの動作確認用になります。- 自作のものか購入したものをローカルのどこかに格納します。(Assets直下でも問題ありません)
- Microsoft AzureのBlob Storageでもその他AWSなど別のサービスでもいいため、
.vrm
のファイルをサーバー上にアップします。(https://○○.blob.core.windows.net/××/fileName.vrm の形式で読み込めるようになっていれば問題ありません。WebGLで読み込む場合、格納場所によってはCORSエラー等で読み込めない場合がありますのでご注意ください。)
2. ローカル上のファイル読み込み
コードがこちら↓
using Cysharp.Threading.Tasks;
using UniGLTF;
using UnityEngine;
using UnityEngine.Networking;
using VRM;
using VRMShaders;
namespace VRMTest
{
public class VRMFileLoader : MonoBehaviour
{
/// <summary>
/// ローカルのものを見に行くかどうか
/// </summary>
[SerializeField] private bool isLoal;
/// <summary>
/// 読み込みたいファイル名
/// </summary>
[SerializeField] private string fileName;
private async void Start()
{
if (isLoal) await LoadLocalVrmFile(fileName);
}
/// <summary>
/// ローカルファイルの読み込み
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private async UniTask LoadLocalVrmFile(string fileName)
{
// 指定したPathにある.vrmのファイルをGLTF形式にパースする
// パースもDisposeしないとメモリリークしてしまうためusingを使用
using var gltfData = new AutoGltfFileParser($"Assets/VRMAvatar/{fileName}.vrm").Parse();
var vrm = new VRMData(gltfData);
// Disposeしないとメモリリークしてしまうためusingを使用
using var context = new VRMImporterContext(vrm);
var instance = await context.LoadAsync(new RuntimeOnlyAwaitCaller());
// シーン上にオブジェクト(メッシュ)表示
instance.ShowMeshes();
}
}
}
注意点
- パースしているところ、
VRMImporterContext
のところ、この2カ所でDisposeをしていますが、それぞれDisposeしてやらないとメモリリークが起きてしまいます。 -
instance.ShowMeshes()
を呼んでやらないと、シーン上に読み込みはされるものの、表示がされないません。
3. サーバー上のファイル読み込み
コードがこちら↓
UnityWebRequest.Get()引数を事前準備でサーバーにあげたファイルのURLを渡してあげてください。
using Cysharp.Threading.Tasks;
using UniGLTF;
using UnityEngine;
using UnityEngine.Networking;
using VRM;
using VRMShaders;
namespace VRMTest
{
public class VRMFileLoader : MonoBehaviour
{
/// <summary>
/// 読み込みたいファイル名
/// </summary>
[SerializeField] private string fileName;
private async void Start()
{
await LoadServerVrmFile(fileName);
}
/// <summary>
/// サーバー上のファイルの読み込み
/// </summary>
/// <param name="fileName"></param>
/// <returns></returns>
private async UniTask LoadServerVrmFile(string fileName)
{
using var webRequest = UnityWebRequest.Get($"https://〇〇.blob.core.windows.net/××/{fileName}.vrm");
await webRequest.SendWebRequest();
// WebRequestで取得した.vrmのByteデータをGLTF形式にパースする
// パースもDisposeしないとメモリリークしてしまうためusingを使用
using var gltfData = new GlbBinaryParser(webRequest.downloadHandler.data, "").Parse();
var vrm = new VRMData(gltfData);
// Disposeしないとメモリリークしてしまうためusingを使用
using var context = new VRMImporterContext(vrm);
var instance = await context.LoadAsync(new RuntimeOnlyAwaitCaller());
// シーン上にオブジェクト表示
instance.ShowMeshes();
}
}
}
注意点
- パースしているところ、
VRMImporterContext
のところ、この2カ所でDisposeをしていますが、それぞれDisposeしてやらないとメモリリークが起きてしまいます。 -
LoadAsync
でnew RuntimeOnlyAwaitCaller
を渡していますが、WebGLで使う場合、new ImmediateCaller
を渡してやらないと読み込みが終わりません。※WebGLはマルチスレッド対応していないため -
instance.ShowMeshes()
を呼んでやらないと、シーン上に読み込みはされるものの、表示がされないません。
まとめ
載せられる画像がなくすみません。。事前準備ができていれば、お手元でもご確認頂けるかと思いますので是非上記コードを試してみてください。改善できる部分等あればご指摘頂ければと思いますので、お気軽にコメントください。
余談ですがStartでもasync
が使えます。
ここまでご覧頂きありがとうございました。