VRoidキャラクターの表情やまばたきの制御方法

前回までの作業で、今回のノベルゲームを作るために必要な最低限の機能が揃いました。さっそくシナリオを書いていきたいところですが、その前にゲームのクオリティを上げるためにもうひと手間加える必要があります。

そのひと手間とは、キャラクターの表情を変更する機能の追加です。今の状態ではキャラクターはずっと真顔のままであまり面白くないので、表情を変更したり、自動的にまばたきをさせる機能を追加してキャラクターをより生き生きとさせてみましょう。


※今回の内容はちょっと難しめです。

VRoidキャラクターの表情について

はじめに、VRoidのキャラクターの表情について簡単に説明しておきます。

まずVRoidのキャラクターは「VRM」という人型モデル用の規格で作られており、「BlendShape」(ブレンドシェイプ)という仕組みを使って表情を変更できるようになっています。

それでUnityにインポートしたVRoidモデルのプレハブを見てみると、「VRMBlendShapeProxy」というコンポーネントがあります。これがブレンドシェイプを使ってキャラクターの表情を決めるコンポーネントです(下図)。

VRM BlendShape Ploxy

したがって、表情を変更したい場合はこのコンポーネントを通してパラメータを制御すれば良いというわけです。

VRoidキャラクターの表情やまばたきを制御するC#スクリプト

それでは、キャラクターの表情やまばたきを制御するC#スクリプトを見てみましょう。

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

public class FaceController : MonoBehaviour
{

  [SerializeField]
  float blinkTime = 0.1f;
  [SerializeField]
  float blinkInterval = 3.0f;

  bool blinkEnabled = true;
  bool blinking = false;
  BlendShapePreset currentFace;
  VRMBlendShapeProxy proxy;

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

    //デフォルトの表情をセット
    currentFace = BlendShapePreset.Neutral;
    proxy.AccumulateValue(currentFace, 1);
    }

  void Update()
  {
    StartCoroutine("AutoBlink");	//文字列で指定する必要あり

    proxy.Apply();
  }

  public void ChangeFace(BlendShapePreset preset = BlendShapePreset.Neutral, bool blink = false)
  {
    blinkEnabled = blink;

    if (!blink)
    {
      StopCoroutine("AutoBlink"); //文字列で指定しないと止まらないので注意
      blinking = false;
      proxy.AccumulateValue(BlendShapePreset.Blink, 0);
    }

    proxy.AccumulateValue(currentFace, 0);	//今の表情を無効化する
    proxy.AccumulateValue(preset, 1);		//新しい表情をセットする

    currentFace = preset;
  }

    IEnumerator AutoBlink()
  {
    if (!blinkEnabled | blinking)
    {
      yield break;
    }

    blinking = true;

    proxy.AccumulateValue(BlendShapePreset.Blink, 0);

    yield return new WaitForSeconds(blinkInterval);

    proxy.AccumulateValue(BlendShapePreset.Blink, 1);

    yield return new WaitForSeconds(blinkTime);

    blinking = false;
  }

}

※使う時はこのスクリプトを各キャラクターのプレハブにアタッチしてください。

スクリプトの解説

表情変更の手順について

VRMキャラクターの表情を変更する方法は何通りか用意されていますが、今回は複数の表情(例:まばたきと笑顔、等)を扱いたいので、

  1. 変更したい表情を登録
  2. 表情を一気に適用

という手順を踏むことにしました。そこでAccumulateValueメソッドで個別に表情を登録し、Update内のApplyメソッドで一括適用、というような処理を行っています。

ちなみにAccumulateValueメソッドの第一引数はBlendShapePresetという表情の列挙型の値、第二引数は表情の適用度合い(0~1。0で無効、1で最大限に適用)を表すfloat型の数値です。

ChangeFaceメソッド

キャラクターの表情を指定した表情に変更します(ついでに、まばたきするかどうかも指定することができます)。元の表情は無効化されます。

AutoBlinkコルーチン

blinkInterval秒後にblinkTime秒間だけ目を閉じます。すでにまばたき処理が行われていたり、まばたきが無効化されているときは実行されません。

Fungusで引数つきのメソッドを呼び出す方法

さて、これで表情を変更したり自動でまばたきをさせたりする機能ができました。次はそれをFungusから呼び出して、会話イベントの中で表情を変化させられるようにする方法を紹介します。

Invoke Methodコマンド

Fungusで特定のゲームオブジェクトのメソッドを呼び出すコマンドは

  1. Call Method
  2. Invoke Method

の2通りあります。今回は引数を持つChangeFaceメソッドを呼び出したいので、より高性能なInvoke Methodコマンドを使いましょう。

任意のブロックのコマンドリストにInvoke Methodコマンドを追加したら、

  • ターゲットオブジェクト:表情を変更したいキャラクターのゲームオブジェクト
  • Target Component:FaceController
  • Target Method:ChangeFace

を指定し、Parametersに表情とまばたきするかどうかを指定してください。例えば、喜んでいる表情(Joy)にしたい場合は次のように設定します。

Invoke Methodコマンドの設定例

この例の場合、実行して下の画像のようになればOKです。

VRoidの表情を変更した場合の例


次のページ→準備中…