Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
12
Help us understand the problem. What are the problem?

More than 1 year has passed since last update.

Organization

VRMのロード、表情をつける、とか。

はじめに

こんにちは、先日VRMを使ってYoutubeの文章スクロール系ゴシップ動画のクソサムネ風の画像を生成するソフトを作ってみました。


ダウンロードはこちらから

絶対言ってないだろこんなこと。
この際VRMのロード、アニメーションなどの動的な扱いを勉強したのでその知見を公開します。入門記事しか書けない…

VRMのロード周り

えむにわ先生のVRMLoadUIを利用しました。何故か僕の環境だと本番環境でファイルブラウザが動作しなかったので今回はRuntimeFileBrowserを利用してファイルブラウズに関する部分を一部書き換えることにします。Unityのウィンドウ上で完結するので便利。
UniRxを使ってファイルをブラウズしてパスを返す部分だけ書き換えて元のラインに返します。
(具体的にはAsyncとFileDialogForWindowsを使っているOpenVRMを後述のOpenVRMWithSimpleLoaderで置き換えます。)
2aee8669-9c3e-40c6-b669-bf0743ee27f3_scaled.jpg
↑こんな感じのUIがUnityのウィンドウ内で生成して返り値でurlを得ることができます。非同期実行。

ファイルブラウザの設定をする

ファイルブラウザに関する様々な設定を行います。具体的には.vrmに限定する、といった絞り込みの設定をします。
名前空間は

using SimpleFileBrowser;

です。

FileBrowser.SetFilters( true, new FileBrowser.Filter( "VRM", ".vrm"));

でVRMファイルのみをブラウザできる絞り込みを追加することができます。

FileBrowser.SetDefaultFilter( ".vrm" );

で初期のフィルタを設定することができます。この場合は.vrmファイルとフォルダのみを表示してくれます。
これらを使ってOpenVRMのファイルブラウザを開く部分を書き換えてみると、

        public void OpenVRMWithSimpleLoader()
        {
            FileBrowser.SetFilters(true, new FileBrowser.Filter("VRM", ".vrm"));
            FileBrowser.SetDefaultFilter(".vrm");
            FileBrowser.AddQuickLink("Users", "C:\\Users", null);
            StartCoroutine(ShowLoadDialogCoroutine());
        }

ShowDialogCoroutine()は後述するメソッドで、実際にファイルブラウザを開く部分を担当しています。

VRMモデルのパスを取得

    IEnumerator ShowLoadDialogCoroutine()
    {
        yield return FileBrowser.WaitForLoadDialog( false, null, "Load File", "Load" );
        Debug.Log( FileBrowser.Success + " " + FileBrowser.Result );
    }

yield return FileBrowser.WaitForLoadDialog( false, null, "Load File", "Load" );でファイル選択画面を開くことができます。取得したパスはFileBrowser.Resultで取得できます。取得したVRMファイルのパスをwwwにぶち込んでデータを取得します。www自体非同期なのでIEnumeratorで実行しましょう。
最後に取得したパスをbyte形式にして本来のラインに戻してやります。

            var www = new WWW("file:///" + FileBrowser.Result);
            yield return www;
            LoadVRM(www.bytes);

WWWは初期化時のパスの頭に"file:///"とつけることでweb上ではなく自分のPC内用のファイルパスを生成してくれます。非同期なのでyield returnすることを忘れずに。
ここまですればVRMLoaderUI側でVRMモデルをロードしてくれます。
これらをまとめると、

        IEnumerator ShowLoadDialogCoroutine()
        {
            yield return FileBrowser.WaitForLoadDialog(false, null, "Load File", "Load");

            Debug.Log(FileBrowser.Success + " " + FileBrowser.Result);
            var www = new WWW("file:///" + FileBrowser.Result);
            yield return www;
            LoadVRM(www.bytes);

        }

という感じになります。
ボタンを押下した際にOpenVRMの代わりにOpenVRMWithSimpleFileLoaderで書き換えてあげればOKです。

VRMに表情をつける

アニメーションをつけるところでVRMの本領が発揮されます。インスタンスしたVRMモデルから動的に要素を取得しなくてはいけないのですが、なかなか簡単です。

ボーンの制御

VRMの便利な点としてアバターごとにバラバラな表情のボーンとかをいい感じにまとめて制御してくれる、というのがあります。

これらのパラメータを弄るだけでモデル制作者側が用意した表情をそのまま使うことができます。モデル制作者側のこだわりとソフト制作者側の利便性を共存させててエモいですね。
キャプチャ136.PNG

Joy(喜)、Angry(怒)、Sorrow(哀)、Fun(楽)、母音(A,I,U,E,O)などの顔にすることができます。

キャプチャ137.PNG

キャプチャ138.PNG

キャプチャ139.PNG

キャプチャ140.PNG
(カワF~~)
VRMBlendShapeProxyにこれらのブレンドシェイプのデータが入っているのでこれを弄って喜怒哀楽の表現を出しましょう。VRMBlendShapeProxy自体はVRMオブジェクトに入っています。

        vbsp = VRM.GetComponent<VRMBlendShapeProxy>();
//喜
        var j = new KeyValuePair<BlendShapePreset, float>(BlendShapePreset.Joy,1);
        vbsp.SetValue(j.Key,j.Value);
//怒
        var a = new KeyValuePair<BlendShapePreset, float>(BlendShapePreset.Angry,1);
        vbsp.SetValue(a.Key,a.Value);
//哀
        var s = new KeyValuePair<BlendShapePreset, float>(BlendShapePreset.Sorrow,1);
        vbsp.SetValue(s.Key,s.Value);
//楽
        var f = new KeyValuePair<BlendShapePreset, float>(BlendShapePreset.Fun,1);
        vbsp.SetValue(f.Key,f.Value);

f.valueの値は[0,1]で自由に取れるのですが、表情を切り替える際に他の表情のキーの値を下げておくことを忘れないようにしましょう。(例えば、「怒」から「楽」に表情を変える際に「怒」のキーの値を下げておきましょう。)

VRMにアニメーションをつける

VRMである時点でHumanoidのアニメーションを使用できることが保証されているのもVRMの利点の一つです。適当なアニメーションを流し込んでみましょう。
AnimatorもVRMオブジェクトにアタッチされています。
C#
var vanim = VRM.GetComponent<Animator>();
vanim.runtimeAnimatorController = m_animationController;//ここに張り付けたいAnimatorを設定

表示名(Controller)と内部の呼び名(runtimeAnimatorController)が違うことに注意です(何故かここですごく詰まった)。
あとはvanimに対しパラメータの変更等を行えば通常通りアニメーションが動きます。

最後に

VRM、便利ですね、クソアプリじゃなくてまともなコンテンツに使っていきたいです。 これVRoidHubが来たら要らない知見になるんじゃ…

参考文献

VRMLoaderUI 0.2 リリース
RuntimeFileBrowser

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
12
Help us understand the problem. What are the problem?