UnityでVRM1.0モデルの表情をスクリプトから変化させる、そう、シンプルにね

課題:VRM1.0でいろいろ変わっちゃったみたい


Vroid Studioで作ったモデルをUnityのスクリプトから表情変化させたかったのですが、VRM1.0で表情の仕様がいろいろと変わったらしく、検索しても古い情報だったりで自分の実現したいこと(表情をチョロっと変えたいだけ)が出てこなかったので、スクリプト書いて置いてみました。ご査収ください。

using System.Collections.Generic;
using UnityEngine;
using UniVRM10;

public class ExpressionChanger : MonoBehaviour
{
    public GameObject model;
    private Vrm10Instance modelVrmInstance;
    private Vrm10RuntimeExpression vrm10RuntimeExpression;

    void Awake()
    {
        if (vrm10RuntimeExpression == null)
        {
            modelVrmInstance = model.GetComponent<Vrm10Instance>();
            vrm10RuntimeExpression =  modelVrmInstance.Runtime.Expression;
        }
    }
 
    void Start()
    {
        // Happyの値を1にする
        vrm10RuntimeExpression.SetWeight(ExpressionKey.Happy, 1f);
    }
}

これだとほかの表情を変化させたときに、Happyの値が1のままになっちゃうので、表情を最初から動かさない場合とかにしか使えません。
元の表情も0になってないですしね。
なのでDoTweenをつかって徐々に変化させるバージョンも置いておきます。

using System.Collections.Generic;
using UnityEngine;
using UniVRM10;
using DG.Tweening;

public class ExpressionChanger : MonoBehaviour
{
    public GameObject model;
    private Vrm10Instance modelVrmInstance;
    private Vrm10RuntimeExpression vrm10RuntimeExpression;

    void Awake()
    {
        if (vrm10RuntimeExpression == null)
        {
            modelVrmInstance = model.GetComponent<Vrm10Instance>();
            vrm10RuntimeExpression =  modelVrmInstance.Runtime.Expression;
        }
    }
    
    void Start()
    {
        ChangeExpression(ExpressionKey.Happy, 1f);
    }

    void ChangeExpression(ExpressionKey key, float weight){
        // 0.5秒かけて指定した表情を変化させる
        DOVirtual.Float(vrm10RuntimeExpression.GetWeight(key), weight, 0.5f, value => vrm10RuntimeExpression.SetWeight(key, value));

        // 表情のリストを作った後、指定した表情のみ削除して、それ以外の表情の値を0.5秒かけて現在の値から0にする
        var expressionList = new List<ExpressionKey>()
        {
            ExpressionKey.Neutral, ExpressionKey.Angry, ExpressionKey.Happy, ExpressionKey.Relaxed, ExpressionKey.Surprised, ExpressionKey.Sad
        };
        expressionList.Remove(key);
        foreach (var zeroKey in expressionList)
        {
            DOVirtual.Float(vrm10RuntimeExpression.GetWeight(zeroKey), 0f, 0.5f, value => vrm10RuntimeExpression.SetWeight(zeroKey, value));
        }
    }
}

表情のリストに口の動きや瞬きは含まれてないので、0になりません。
また、自分で追加した表情とかも0にならないので、そのあたりを調整したい場合はコード内のリストを作成している場所に書き加えるといいと思います。

まとめ

自由に使ってネ!


この記事が気に入ったらサポートをしてみませんか?