【Unity】VRoidStudioで作ったキャラクターと戯れる 〜表情操作とアニメーション作成〜

Unity
マイケル
マイケル
みなさんこんにちは!
マイケルです!!
エレキベア
エレキベア
こんにちクマ〜〜〜
マイケル
マイケル
今日は前回に引き続き、
VRoidStudioで作ったモデルを触っていこうと思います!
01 aoba↑前回の成果
マイケル
マイケル
とりあえずアセットのアニメーションを使って動かすことはできたけど
何だか物足りない・・・
表情を付けて、アニメーションも自分で作ってみよう!
エレキベア
エレキベア
楽しみクマ〜〜〜
スポンサーリンク

表情を変えてみる

マイケル
マイケル
それじゃ手始めに表情を変えてみよう!
実はVRoidStudioで作ったモデルには既に、デフォルトで表情が割り当てられています!
ScreenShot 2021 11 29 23 02 10↑BlendShapeファイルとして設定されている
ScreenShot 2021 11 29 23 02 32↑エディタ上で表情を変えて確認することもできる
エレキベア
エレキベア
VRoidStudio便利すぎクマ
マイケル
マイケル
この表情をスクリプト上から呼び出してみよう!
まず準備としてAnimationControllerは下記のように設定します!
ScreenShot 2021 11 27 0 20 25↑AnimationControllerの設定
マイケル
マイケル
表情はImmediatelySetValueメソッドを呼び出すことで設定できます!
下記スクリプトを、VRMBlendShapeProxy
アタッチされたオブジェクトに追加しましょう!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRM;

/// <summary>
/// 青葉操作クラス
/// </summary>
public class AobaController : MonoBehaviour
{
    private VRMBlendShapeProxy _blendShapes;
    private Animator _animator;
    
    void Start()
    {
        _blendShapes = GetComponent<VRMBlendShapeProxy>();
        _animator = GetComponent<Animator>();
    }
    
    void Update()
    {
        // タップされたら怒る
        if (Input.GetMouseButtonDown(0))
        {
            _animator.SetTrigger("isAngry");
        }
        
        // 怒っていれば呆れる
        var isAngry = _animator.GetCurrentAnimatorClipInfo(0)[0].clip.name == "AGIA_Idle_angry_01_hands_on_waist";
        _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Sorrow), isAngry ? 1.0f : 0.0f);
    }
}
↑アニメーションによって表情を変える
01 BlendShape
マイケル
マイケル
すると、このように表情が変わることを確認できました!
エレキベア
エレキベア
簡単クマ〜〜〜〜

表情を作ってみる

マイケル
マイケル
それでは次に表情を作ってみましょう!
BlendShapeファイルからCreate BlendShapeClipボタンをクリックしてファイルを作成します。
ScreenShot 2021 11 27 0 22 11
マイケル
マイケル
ここでは名前をCrazyとします。
エレキベア
エレキベア
(クレイジー・・・?)
ScreenShot 2021 11 27 0 24 24
マイケル
マイケル
作成したら、自由にスライダーを調整して表情を作りましょう!
ScreenShot 2021 11 27 1 24 47↑表情の編集
エレキベア
エレキベア
(なんだこの顔はクマ・・・)
マイケル
マイケル
選択するプリセットについては、glTF_VRM_BlendShape.cs
に追記することで追加できます!
    public enum BlendShapePreset
    {
・・・略・・・

        Crazy, // 追加

    }

    [Serializable]
    [JsonSchema(Title = "vrm.blendshape.group", Description = "BlendShapeClip of UniVRM")]
    public class glTF_VRM_BlendShapeGroup
    {
        [JsonSchema(Description = "Expression name")]
        public string name;

        [JsonSchema(Description = "Predefined Expression name", EnumValues = new object[] {
・・・略・・・

            "Crazy", // 追加

        }, EnumSerializationType = EnumSerializationType.AsString)]
・・・略・・・
    }
↑Presetの追加
マイケル
マイケル
あとは先ほどと同じように、表情のパラメータを変更することで
設定することができます!
ScreenShot 2021 11 27 0 41 21
02 crazy
エレキベア
エレキベア
(やる気なさそうクマ・・・)
マイケル
マイケル
これをスクリプトからも呼び出してみましょう!
雑ですが下記のようにしてみます!!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using VRM;

/// <summary>
/// 青葉操作クラス
/// </summary>
public class AobaController : MonoBehaviour
{
    private VRMBlendShapeProxy _blendShapes;
    private Animator _animator;
    
    /// <summary>
    /// クレイジー判定用
    /// </summary>
    private float _crazyChangeTime = 3.0f;
    private float _crazyTotalTime;
    private float _crazyValue;
    private bool _isCrazy;
    
    void Start()
    {
        _blendShapes = GetComponent<VRMBlendShapeProxy>();
        _animator = GetComponent<Animator>();
        // クレイジー用変数初期化
        _crazyTotalTime = 0.0f;
        _crazyValue = 0.0f;
        _isCrazy = false;
    }
    
    void Update()
    {
        // タップされたら怒る
        if (Input.GetMouseButtonDown(0))
        {
            _animator.SetTrigger("isAngry");
        }
        
        // 怒っていれば呆れる
        var isAngry = _animator.GetCurrentAnimatorClipInfo(0)[0].clip.name == "AGIA_Idle_angry_01_hands_on_waist";
        if (isAngry)
        {
            _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Crazy), 0.0f);
            _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Sorrow), 1.0f);
        }
        else
        {
            // 一定間隔でクレイジーになる
            _crazyTotalTime += Time.deltaTime;
            if (_crazyTotalTime >= _crazyChangeTime)
            {
                _isCrazy = !_isCrazy;
                _crazyTotalTime = 0.0f;
            }
            _crazyValue = Mathf.Lerp(_crazyValue, _isCrazy ? 1.0f : 0.0f, _crazyTotalTime * 3.0f);
            _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Crazy), _crazyValue);
        }
    }
}
03 crazy 02
マイケル
マイケル
問題なく表情が変わっていることが確認できました
エレキベア
エレキベア
人間らしさが出てきたクマ〜〜〜

がんば●ぞいを作る

マイケル
マイケル
表情の操作を覚えたところで、オリジナルの動きも作ってみましょう!
ここでは例の がんばるぞい っぽいのを作ってみます!
エレキベア
エレキベア
有名なやつクマね

表情の作成

マイケル
マイケル
まずは表情の作成!
Fightという名前で作ってみました!
ScreenShot 2021 11 27 1 39 52↑がんばってそうな表情
04 fight face
マイケル
マイケル
変化が少ないけどまあいいでしょう!
エレキベア
エレキベア
(いいのかクマ・・・)

動きの作成

マイケル
マイケル
そして次はアニメーションを作ります!
外部の3Dツールを使用してもいいですが、ここではUnity内部で作成できるVery Animationというアセットを使用しました!

マイケル
マイケル
Very Animationは下記の記事で紹介しているので
こちらも是非みてみてください!
エレキベア
エレキベア
なつかしクマ〜〜〜〜
マイケル
マイケル
手順はざっくりですが下記の通り!
ScreenShot 2021 11 28 12 38 37↑アニメーションファイルの作成
ScreenShot 2021 11 28 12 39 07↑AnimationControllerへの追加
ScreenShot 2021 11 28 12 41 02↑Very Animationでアニメーションを選択
ScreenShot 2021 11 28 12 41 24↑ボーンを動かしてアニメーションを作る
ScreenShot 2021 11 28 12 41 32↑キーフレームは地道に調整する
エレキベア
エレキベア
(マジでざっくりクマ・・・。)
マイケル
マイケル
そんな感じで出来たアニメーションがこちら!
05 zoi
エレキベア
エレキベア
違和感あるクマがそれっぽいクマね

組み合わせる

マイケル
マイケル
あとは表情とアニメーションを組み合わせましょう!
まずはアニメーションを呼び出すためのボタンを用意して・・・
ScreenShot 2021 11 28 13 28 47↑ぞいボタンの追加
マイケル
マイケル
下記のようにそれぞれのアニメーションに対する表情を設定します!
さっきよりは綺麗になったんじゃないかな!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using VRM;

/// <summary>
/// 青葉操作クラス
/// </summary>
public class AobaController : MonoBehaviour
{
    private VRMBlendShapeProxy _blendShapes;
    private Animator _animator;
    
    /// <summary>
    /// クレイジー判定用
    /// </summary>
    private float _crazyChangeTime = 3.0f;
    private float _crazyTotalTime;
    private float _crazyValue;
    private bool _isCrazy;

    void Start()
    {
        _blendShapes = GetComponent<VRMBlendShapeProxy>();
        _animator = GetComponent<Animator>();
        // クレイジー用変数初期化
        _crazyTotalTime = 0.0f;
        _crazyValue = 0.0f;
        _isCrazy = false;
    }
    
    void Update()
    {
        // 表情初期化
        _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Fight), 0.0f);
        _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Crazy), 0.0f);
        _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Sorrow), 0.0f);
        
        // 再生中のアニメーションに合わせて処理を変える
        switch (_animator.GetCurrentAnimatorClipInfo(0)[0].clip.name)
        {
            // がんばるぞい
            case "Fight":
                _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Fight), 1.0f);
                break;
            // 怒っている
            case "AGIA_Idle_angry_01_hands_on_waist":
                _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Sorrow), 1.0f);
                break;
            // 通常
            default:
                // タップされたら怒る
                if (!EventSystem.current.IsPointerOverGameObject() && Input.GetMouseButtonDown(0))
                {
                    _animator.SetTrigger("isAngry");
                }
                // 一定間隔でクレイジーになる
                _crazyTotalTime += Time.deltaTime;
                if (_crazyTotalTime >= _crazyChangeTime)
                {
                    _isCrazy = !_isCrazy;
                    _crazyTotalTime = 0.0f;
                }
                _crazyValue = Mathf.Lerp(_crazyValue, _isCrazy ? 1.0f : 0.0f, _crazyTotalTime * 3.0f);
                _blendShapes.ImmediatelySetValue(BlendShapeKey.CreateFromPreset(BlendShapePreset.Crazy), _crazyValue);
                break;
                
        }
    }

    /// <summary>
    /// ぞいボタン押下時
    /// </summary>
    public void PushZoiButton()
    {
        _animator.SetTrigger("isFight");
    }
}
↑アニメーション呼び出しと表情設定
マイケル
マイケル
これでがんばるぞいの完成です!!
06 zoi button
エレキベア
エレキベア
かわいいクマ〜〜〜〜〜

まだまだ改良

マイケル
マイケル
しかしまだまだ迫力が足りない・・・!
改良していくぜ!
エレキベア
エレキベア
(これに迫力は必要なのかクマ・・・)
マイケル
マイケル
まずは下記のようにがんばるぞい用のサブカメラを作成します!
ScreenShot 2021 11 28 14 47 55↑サブカメラの作成
マイケル
マイケル
そしてセリフ表示用のCanvasを作成して、
アニメーションをつけたセリフを配置します!
ScreenShot 2021 11 28 14 48 24↑セリフ表示用Canvasの作成
08 zoi msg↑セリフのアニメーション
マイケル
マイケル
あとはこれらを切り替える関数とクラスを用意して・・・
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// Scene管理クラス
/// </summary>
public class SceneManager : MonoBehaviour
{
    /// <summary>
    /// Camera関連
    /// </summary>
    [SerializeField] private Camera _mainCamera;
    [SerializeField] private Camera _zoiCamera;
    
    /// <summary>
    /// Canvas関連
    /// </summary>
    [SerializeField] private GameObject _mainCanvas;
    [SerializeField] private GameObject _zoiCanvas;
    
    void Start()
    {
        SetMainDisplay();
    }

    /// <summary>
    /// メインの表示
    /// </summary>
    public void SetMainDisplay()
    {
        _mainCamera.gameObject.SetActive(true);
        _zoiCamera.gameObject.SetActive(false);
        
        _mainCanvas.SetActive(true);
        _zoiCanvas.SetActive(false);
    }
    
    /// <summary>
    /// ぞいアニメーション用の表示
    /// </summary>
    public void SetZoiDisplay()
    {
        _mainCamera.gameObject.SetActive(false);
        _zoiCamera.gameObject.SetActive(true);
        
        _mainCanvas.SetActive(false);
        _zoiCanvas.SetActive(true);
    }
}
マイケル
マイケル
アニメーション開始時と終わりに切り替えてあげれば完成!!
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using VRM;

/// <summary>
/// 青葉操作クラス
/// </summary>
public class AobaController : MonoBehaviour
{
    /// <summary>
    /// Scene管理クラス
    /// </summary>
    private SceneManager _sceneManager;

・・・略・・・

    void Start()
    {
        _sceneManager = FindObjectOfType<SceneManager>();
・・・略・・・
    }

・・・略・・・

    /// <summary>
    /// ぞいボタン押下時
    /// </summary>
    public void PushZoiButton()
    {
        _animator.SetTrigger("isFight");
        _sceneManager.SetZoiDisplay();
    }

    /// <summary>
    /// ぞいアニメーション終了時
    /// </summary>
    public void EndZoiAnimation()
    {
        _sceneManager.SetMainDisplay();
    }
}
ScreenShot 2021 11 29 0 57 47↑アニメーション終了イベント
マイケル
マイケル
これでどうだ!!!
07 zoi complete↑がんばるぞいの完成
エレキベア
エレキベア
おおーー!!
なんか見栄えがよくなったクマ〜〜!!
マイケル
マイケル
だいぶキャラクターが活きてきたね!!
(動きは違和感あるけど・・・)

おわりに

マイケル
マイケル
というわけで今回はVRoidStudioで作ったキャラの表情操作と
アニメーション作成でした!
どうだったかな??
エレキベア
エレキベア
やっぱりキャラクターを動かすのは楽しいクマね
だんだんと愛着も湧いてくるクマ
マイケル
マイケル
楽しいしやっぱりかわいいね!
もっと思い通りに動かしたいね!!
かわいいね!
エレキベア
エレキベア
(キモいクマ・・・)
マイケル
マイケル
それでは今日はこの辺で!
アデュー!!!
エレキベア
エレキベア
クマ〜〜〜〜〜

【Unity】VRoidStudioで作ったキャラクターと戯れる 〜表情操作とアニメーション作成〜

コメント