4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【VTuber】Oculus touchで表情を変えてみる

Last updated at Posted at 2018-03-28

OculusTouchのボタンを使って表情を変える方法を紹介します。

ボタンの入力操作につきましては、こちらの記事を参考にさせていただきました。
https://framesynthesis.jp/tech/unity/touch/

完成イメージ

kizunaai_facecontroller_gif.gif

用意するもの

制作の流れ

ボタンを押したときの処理を書く

アタッチしたオブジェクトの、SkinnedMeshRendererの値を指定する

以上。

ボタンに応じて表情を変更させる

OculusTouchを使うにはOVRのライブラリを使わないといけません。

ということで、Oculus Utilities for Unityをプロジェクトにインポートします。

そしたらOVR > Prefab > OVRcameraRigを適当に配置しましょう。
image.png

次にボタンに関するスクリプトを用意ます。今回はFaceController.csとしました。

以下のコードを書いて、モデルやカメラにアタッチしてください。(どこでも構いません)

FaceController.cs
public class FaceController : MonoBehaviour {
    public SkinnedMeshRenderer skinnedMeshRenderer = null;
    // Use this for initialization
    void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        //押したときの処理
        if (OVRInput.GetDown(OVRInput.RawButton.A))
        {
            //喜
            Debug.Log("Aボタンを押した");
            skinnedMeshRenderer.SetBlendShapeWeight(0, 100f);
        }
        if (OVRInput.GetDown(OVRInput.RawButton.B))
        {
            //怒
            Debug.Log("Bボタンを押した");
            skinnedMeshRenderer.SetBlendShapeWeight(25, 100f);
        }
        if (OVRInput.GetDown(OVRInput.RawButton.X))
        {
            //哀
            Debug.Log("Xボタンを押した");
            skinnedMeshRenderer.SetBlendShapeWeight(7, 100f);
        }
        if (OVRInput.GetDown(OVRInput.RawButton.Y))
        {
            //楽
            Debug.Log("Yボタンを押した");
            skinnedMeshRenderer.SetBlendShapeWeight(22, 100f);
        }
        if (OVRInput.GetDown(OVRInput.RawButton.Start))
        {
            //死んだ目
            Debug.Log("メニューボタン(左アナログスティックの下にある)を押した");
            skinnedMeshRenderer.SetBlendShapeWeight(30, 100f);
        }

        if (OVRInput.GetDown(OVRInput.RawButton.RIndexTrigger))
        {
            //右ウィンク
            Debug.Log("右人差し指トリガーを押した");
            skinnedMeshRenderer.SetBlendShapeWeight(3, 100f);
        }
        if (OVRInput.GetDown(OVRInput.RawButton.RHandTrigger))
        {
            //まばたき
            Debug.Log("右中指トリガーを押した");
            skinnedMeshRenderer.SetBlendShapeWeight(1, 100f);
        }
        if (OVRInput.GetDown(OVRInput.RawButton.LIndexTrigger))
        {
            //左ウィンク
            Debug.Log("左人差し指トリガーを押した");
            skinnedMeshRenderer.SetBlendShapeWeight(2, 100f);
        }
        if (OVRInput.GetDown(OVRInput.RawButton.LHandTrigger))
        {
            //じと目
            Debug.Log("左中指トリガーを押した");
            skinnedMeshRenderer.SetBlendShapeWeight(8, 100f);
        }

        //離したときの処理
        if (OVRInput.GetUp(OVRInput.RawButton.A))
        {
            Debug.Log("Aボタンを離した");
            skinnedMeshRenderer.SetBlendShapeWeight(0, 0f);
        }
        if (OVRInput.GetUp(OVRInput.RawButton.B))
        {
            skinnedMeshRenderer.SetBlendShapeWeight(25, 0f);
        }
        if (OVRInput.GetUp(OVRInput.RawButton.X))
        {
            skinnedMeshRenderer.SetBlendShapeWeight(7, 0f);
        }
        if (OVRInput.GetUp(OVRInput.RawButton.Y))
        {
            skinnedMeshRenderer.SetBlendShapeWeight(22, 0f);
        }
        if (OVRInput.GetUp(OVRInput.RawButton.Start))
        {
            skinnedMeshRenderer.SetBlendShapeWeight(30, 0f);
        }

        if (OVRInput.GetUp(OVRInput.RawButton.RIndexTrigger))
        {
            skinnedMeshRenderer.SetBlendShapeWeight(3, 0f);
        }
        if (OVRInput.GetUp(OVRInput.RawButton.RHandTrigger))
        {
            skinnedMeshRenderer.SetBlendShapeWeight(1, 0f);
        }
        if (OVRInput.GetUp(OVRInput.RawButton.LIndexTrigger))
        {
            skinnedMeshRenderer.SetBlendShapeWeight(2, 0f);
        }
        if (OVRInput.GetUp(OVRInput.RawButton.LHandTrigger))
        {
            skinnedMeshRenderer.SetBlendShapeWeight(8, 0f);
        }
    }
}

するとSkinned Mesh Rendererにオブジェクトを入れる欄があるので、ここに顔に当たるオブジェクトをアタッチしておきます。
image.png
スクリプトに顔を受け取ることで、 skinnedMeshRenderer.SetBlendShapeWeight(1, 100f); で自由に動かせるようになりました。

skinnedMeshRenderer.SetBlendShapeWeight(1, 100f); にある、(1, 100f) に注目してください。

この第一引数(ここでいう1)が、表情のインデックス番号、第二引数(ここでいう100f)がインデックス番号の値になります。

このインデックス番号については、スクリプトにアタッチしたオブジェクト > BlendShapesから確かめることが可能。
index_number.PNG

キャラによって種類や数が違いますが、一番左の番号がインデックス番号で、それぞれ値を変更できることが分かると思います。

例えば、笑いを100、「あ」の口の形を100にしてみると、モデルもそれにしたがって表情が変更されることに気づくかと思います。
image.png

ぜひ一度確かめてみてください。

後はボタンに応じて、モーフのインデックス番号、それに対する値をそれぞれ指定するだけですね。

実際にボタンを押して指定した表情になるのか確かめてみてください。

まとめ

口に関してはマイクからリップシンクさせつつ、表情はボタンで変えるということをしてみました。

今回はキズナアイモデルを使いましたが、キャラによって顔のオブジェクトの場所、表情の種類が違うので、別のキャラを使う方には各自探していただく形になるかもしれません。

もし音声からもリップシンクさせたい!という方はそちらもまとめましたので参考にしていただければと。
https://qiita.com/ngron/items/b2c02a0f8133aac2ad9a

4
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?