【Unity×VRM1.0】任意のVRMファイルをフォルダから選択し読み込む

# 概要
Unityで任意のVRMファイルをフォルダから選択し読み込むまでのデモです。

![2024-02-04 20-51-09.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3604990/12f2c0a4-a304-7f64-c26a-6e532942df84.gif)

# 開発環境
Windows 10
Unity 2022.3.6f1
Api Compatibility Level .NET Standard 2.1

# 使用したパッケージ
### VRM 1.0
リンク先からunitypackageをダウンロード、事前にプロジェクトにインポートしておきます。
https://github.com/vrm-c/UniVRM
なお、利用したのはVRM-0.117.0_9a91.unitypackageです。

VRMの実装に関しては、以下が参考になりました。

https://www.youtube.com/watch?v=iWucttIioRk&t=5274s

https://sheltie-garage.xyz/tech/2023/05/unity%E3%81%A7vrm1-0%E3%81%AEvrm%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%93%E3%81%A7%E3%81%BF%E3%82%8B/

### Unity Standalone File Browser
こちらは、フォルダからファイルを読み込むのに利用しました。
Windowsでしか試していませんが、クロスプラットフォーム対応できるようです。素晴らしい！

リンク先からunitypackageをダウンロード、事前にプロジェクトにインポートしておきます。
https://github.com/gkngkc/UnityStandaloneFileBrowser

実装に関しては、githubに記載のあるExample usageとサンプルシーン(Sample/BasicSampleScene.unity)を参考にしました。

# 実装
### スクリプト
C#スクリプトは以下の通りです。
今回は"Load VRM"ボタンをクリックするとエクスプローラーが開いて、任意のVRMファイルを読み込めるようにしています。
ボタンの実装はCanvasを利用していますが、その説明はここでは行いませんので、参考資料を最後に載せておきました。
また、以下の投稿でCanvasのテスト実装を試しているので、参考にしていただければと思います。
https://qiita.com/Gamo_2683/items/0894bfb34b2b14b32e96

publicで定義したLoadVRM()関数をButtonコンポーネントのOn Click()にセットすれば、ボタンクリック時の動きが定義できるのですが、関数をTaskで書くとOn Click()にセットできる関数の一覧に表示されなかったため、気持ちが悪いですがTaskで書く必要のある処理はOpenVRM()関数として別定義しています。
このあたりの仕様は追々確認が必要そうです。

```csharp:UniVrm10.cs
using UnityEngine;
using System.Threading.Tasks;
using UniVRM10;
using SFB;

public class UniVrm10 : MonoBehaviour
{
    // デフォルトで読み込みたいモデルがある場合はpathをセットする。
    string path = "";

    // Open file with filter
    // 拡張子がvrmまたはVRMのファイルのみ選択させる。
    ExtensionFilter[] extensions = new[] {
        new ExtensionFilter("VRM Files", "vrm", "VRM"),
    };

    // Start is called before the first frame update
    async void Start()
    {
        if (path != "" && path != null)
        {
            // VRMファイルのロード
            Vrm10Instance vrm10Instance = await Vrm10.LoadPathAsync(path);
        }

    }

    // Update is called once per frame
    void Update() { }

    // ButtonコンポーネントとOn Click()にセットして利用することを想定
    public void LaodVRM()
    {
        string[] paths = StandaloneFileBrowser.OpenFilePanel("Load VRM File", "", extensions, true);
        // Vrm10Instance vrm10Instance = await Vrm10.LoadPathAsync(paths[0]);

        // すでに開かれているVRMファイルがある場合は削除する。
        GameObject currentVrm = GameObject.Find("VRM1");
        if (currentVrm != null)
        {
            Destroy(currentVrm);
        }
        OpenVRM(paths);
    }

    private async Task OpenVRM(string[] paths)
    {
        // VRMファイルのロード
        Vrm10Instance vrm10Instance = await Vrm10.LoadPathAsync(paths[0]);
    }
}
```

# 利用方法
* Unityを起動します。
* 使用するUnityパッケージをインポートします。
* Emptyオブジェクトを用意します。
* 用意したEmptyオブジェクトのコンポーネントにUniVRM10.csをセットします。
* GameObject>UIからCanvasを用意します。
* 同様にGameObject>UIからButton - TextMeshProを用意します。
* ButtonコンポーネントのOn Click()のSelect Objectにはじめに作成したEmptyオブジェクトをセットします。続いて、UniVrm10>LaodVRM()の順に選択して、クリック時に実行する関数を指定します。
* Playモードに入ります。
* Buttonをクリックして、読み込みたいVRMファイルを読み込むことができたら成功です。

# はじめのデモ画像（GIF）で使用したアバター
２つ目のアバターは2024/2/5時点で無料配布されているとてもかわいいガニ股で歩く無料3D美少女アバターですが、vrmは同梱されていないため、自力で変換する必要があります。
今回は製作者のひまたさんのご厚意でご提供いただきました。感謝です！

1\. New NecoMaid（製作：QuQu）

https://sonovr.booth.pm/items/4252664

2\. がにまた（製作：ひまた工房）

https://himata.booth.pm/items/4169367

3\. 薄荷（製作：mio3io）

https://mio3works.booth.pm/items/2215270

# 参考資料
### VRM関連

https://github.com/vrm-c/UniVRM

https://www.youtube.com/watch?v=iWucttIioRk&t=5274s

https://sheltie-garage.xyz/tech/2023/05/unity%E3%81%A7vrm1-0%E3%81%AEvrm%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%92%E8%AA%AD%E3%81%BF%E8%BE%BC%E3%82%93%E3%81%A7%E3%81%BF%E3%82%8B/

### Unity Standalone File Browser関連

https://github.com/gkngkc/UnityStandaloneFileBrowser

### Canvas関連

https://www.metalbrage.com/UnityTutorials/uGUI/Canvas.html

https://xr-hub.com/archives/11782

https://note.com/morikikuma/n/n90196412f5e2