VRM形式のアバターをCandy Rock Starに持ち込んで躍らせる(UniVRM0.61版)


背景

VRM Live Viewerを使えばUnite In the Skyを簡単に躍らせることができます。

VRM Live Viewer - Fantom工房 - BOOTH
YouTubeで関連動画を探してみると、VRM Live Viewerを使って撮影したものよりもはるかにきれいな動画の物がありました。
本家はCandy Rock Starという、Unityちゃんの公式コンテンツのようです。

VRM Live Viewerとの大きな違いは以下の点でしょう。

  • カメラの動きがなめらか、複数カメラのスイッチによるカメラワーク
  • 被写界深度表現やブルーム

やること

Candy Rock Starのプロジェクトデータは無料で使用可能なライセンスで公開されているようなので、これを使って動画を作成してみようと思います。

環境

Windows 10
Unity 2018.4.14f1
UniVRM 0.61.1

参考にした記事・この記事で解説すること

VRMモデルをCandy Rock Starプロジェクトにインポートして動かす手順については、以下の記事に解説がありました。

【Unity初心者向け】VRMモデルでCandy Rock Star踊ってみた

この記事では、上記の記事通りにやってもうまくいかなかった部分について解消方法について補足します。

遭遇したエラー

FocusPullHelperでNullReferenceExceptionが発生し、開幕ピンボケになる

Playすると読み込んだVRMが表示されて動き出しましたが、以下のようなエラーメッセージがエディタ下部に表示されていました。

NullReferenceException: Object reference not set to an instance of an object
FocusPullerHelper.Start() (at Assets/PostProcessing/FocusPullerHelper.cs: 24)

Focus(ピント)関係のエラーのようですが、言われてみれば確かに開幕で妙にピントがボケています。

FocusPullerHelperの24行目を見ると以下のコードがありました。
FocusObjというタグがついているオブジェクトを取得して、trasnformコンポーネントを取得しようとしているようですが、FocusObjタグのついたオブジェクトが見つからず、nullからtransformを取得しようとしてしまっているようです。

focusObj = GameObject.FindGameObjectWithTag("FocusObj").transform;

元から入っていたUnityちゃんのPrefabではルートオブジェクトにFocusObjタグが設定されていましたので、同じように設定します。

Asset内のVRMアバターのPrefab Assetをダブルクリックすることでヒエラルキーに表示し、ヒエラルキーのルートのオブジェクトを選択します。InspectorのTagを見るとUntaggedとなっているので、FocusObjに変更します。

これでエラーは解消し、開幕からピントがばっちり合うようになりました。

なお、下からのアングルの時に顔にフォーカスが合ってなかったので、FocusObjタグをHeadボーンに付けるようにしたところ顔にピントが合いました。ただ、僕のモデルの場合頭身が低い(頭が大きい)せいか顔アップで奥ピンになってしまうようでした。

歩いているのにアバターがステージ中央から移動しない

アバターのAnimatorコンポーネントのApply Root Motionにチェックを入れる必要があります。
AnimatorコンポーネントはAssets内のアバターのPrefabをダブルクリックしてヒエラルキーに表示し、ルートオブジェクトを選択することでInspectorに表示されます。

参考にした記事にもApply Root Motionにチェックを入れると書いてありますが見落としてました……

表情モーフが反映されない

UniVRMのバージョンアップの影響で、ブレンドシェイプへのアクセス方法が変わったようです。
UniVRM v0.61.1の時点ではImmediatelySetValueでもSetValueでもなく、SetValuesメソッドを使うようです。そこでFaceChanger.csを以下のように書き換えました。(なお、コンパイルが通ることは確認しましたが、僕のモデルではBLINK以外の表情は入っていないため、それらの表情の動作は未確認です)

BlendShapeを操作する| VRM

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRM;

public class FaceChanger : MonoBehaviour
{
    VRMBlendShapeProxy proxy;

    void Start()
    {
        proxy = GetComponent<VRMBlendShapeProxy>();
    }

    //表情を変えるイベントをここで受け取る.
    public void OnCallChangeFace(string str)
    {
        Debug.Log("FaceChanger#OnCalleChangeFace:" + str);

        switch (str)
        {                                    //受け取ったメッセージが
            case "eye_close@unitychan":                 //「目を閉じる」であれば
                proxy.SetValues(new Dictionary<BlendShapeKey, float>
                { {BlendShapeKey.CreateFromPreset(BlendShapePreset.Blink), 1f } });   // 瞬き
                break;
            case "smile3@unitychan":                    //「笑顔」であれば
                proxy.SetValues(new Dictionary<BlendShapeKey, float>
                { {BlendShapeKey.CreateFromPreset(BlendShapePreset.Joy), 1f } });   // 喜
                break;
            case "conf@unitychan":                      //「困惑」であれば
                proxy.SetValues(new Dictionary<BlendShapeKey, float>
                { {BlendShapeKey.CreateFromPreset(BlendShapePreset.Angry), 1f } });   // 怒
                break;
            case "default@unitychan":                   //それ以外なら
                proxy.SetValues(new Dictionary<BlendShapeKey, float>
                {
                    {BlendShapeKey.CreateFromPreset(BlendShapePreset.Blink), 0f } ,
                    {BlendShapeKey.CreateFromPreset(BlendShapePreset.Joy), 0f } ,
                    {BlendShapeKey.CreateFromPreset(BlendShapePreset.Angry), 0f } ,
                });   //すべてリセット
                break;
        }
    }
}

自分の環境ではVRMの読み込みにv0.55を使っていたのにv0.61のドキュメントを参照していたため、インポートしたプロジェクト内からBlendShapePreset列挙体の要素が未定義でコンパイルエラーが発生したりしてプチハマりした(でもエラーが出てくれるだけありがたい)。UniVRMのバージョンには気をつけよう。

OnCallMusicPlayのレシーバーが無いと言われる

エディタ下部には以下のようなエラーメッセージも表示されていました。

'<VRMファイル名>(Clone)'AnimationEvent 'OnCallMusicPlay' has no receiver! Are you missing a component?

Unityちゃんのコンポーネントからスクリプトを探してみると、MusicStartar.csファイルの中にOnCallMusicPlay()メソッドが見つかりました。内容を見てみると、音楽を再生するためのコードのようです。ここでエラーが出ていても問題なく音楽は再生できているようなので、特に対応はせずそのままにします。

その他エラー

CameraSwitcherでNullReferenceExceptionが出る→Camera Targetの名前が間違ってるかも

成果物

以上の設定を行い、録画・編集したものをアップロードしました!