LoginSignup
53
51

More than 3 years have passed since last update.

【VTuber】OVRLipsyncでUnity上のキャラをリップシンクさせる方法

Last updated at Posted at 2018-03-28

Unity上のキャラをリップシンクさせるには二通りあります。
1つ目はMMD4MecanmLipSyncPlugin、2つ目がOVRLipsyncを使う方法。

しかし、Oculusのほうが精度が高いと感じたため、今回はOVRLipsyncを使ってリップシンクさせる方法をまとめてみました。

こちらの記事を参考にさせていただいております。
http://tips.hecomi.com/entry/2016/02/16/202634

完成イメージ

kizunaai_lipsync3_gif.gif

用意するもの

OVRLipsyncをダウンロードして、空オブジェクトにアタッチする

OVRLipsyncをダウンロードしてインポートします。

そしたら空オブジェクトを作成しましょう。
image.png

空のObjectにOVRLipSyncをアタッチ。
image.png

音声によって口の動きを変形させられるようにする

キズナアイ(3Dモデル)Objectに
OVRLipSyncContext ,
OVRLipSyncContextMorphTarget
をアタッチ。
image.png

OVRLipSyncMorphTarget > Skinned Mesh Rendererに、頭のパーツを当てはめましょう。キャラによって違いますが、キズナアイの場合はU_char_1になります。
image.png
これによって、キズナアイのモーフを操れるようになりました。

もし「どれを当てはめるのか分からない!」という方は頭周辺のパーツを探りBlendShapesが付いているものを当ててみるといいかも。

image.png

次にOVRLipSyncMorphTarget > Viseme To Blend を開き、
Targetの母音部分を対象のモーフのインデックス番号を指定します。
image.png

まず、Visme To Blendは15種類の口形素があります。(詳しくはこちらに載ってますが勉強する必要はありません)
0 sil(無音)
1 PP(p,m,b)
2 FF(f,v)
3 EH(@r)
4 DD(t,d)
5 kk(k,g,x)
6 CH(tS,S,Z)
7 SS(ts,s,z)
8 nn(n,l,r)
9 RR(@r)
10 aa(あ)
11 E(え)  
12 ih(い)  
13 oh(お)
14 ou(う)

例えば、「あ」と、発音したしたときに、Element10に当てはめたモーフのインデックス番号が反映される仕組みです。
モーフのインデックス番号はSkinned Mesh Renderer > BlendShapesから確認できます。
image.png
ここでは1~32がインデックス番号に当たり、その番号に対するモーフ(表情)がそれぞれ対応しています(キャラによって数が違う)
中でも、9 →「あ」、10 → 「い」 11 → 「う」12 → 「え」13 → 「お」となっていることに気づくと思います。

これらが、先程当てはめたモーフ番号になります。
つまり、現状ではこんな感じ。

発音 インデックス番号 口の形
0 sil(無音) 0
1 PP(p,m,b) 0
2 FF(f,v) 0
3 EH(@r) 0
5 kk(k,g,x) 0
6 CH(tS,S,Z) 0
7 SS(ts,s,z) 0
8 nn(n,l,r) 0
9 RR(@r) 0
10 aa(あ) 9
11 E(え) 12
12 ih(い) 10
13 oh(お) 13
14 ou(う) 11

10 aa(あ)と発音したときに、9「あ」の口の形をする
14 ou(お)と発音したときに、14「お」の口の形をする
といった感じです。

他にも、pp であれば「ポ」、FFなら「ファ」の発音になるので、それぞれの発音に対するモーフを当てはめていただけれければと。

次に、OVRLipSyncContextMorphTargetのUpdate()LateUpdate()に変更しておきます。

OVRLipSyncContextMorphTarget.sc

void LateUpdate () {
  if ((lipsyncContext != null) && (skinnedMeshRenderer != null)) {
    // trap inputs and send signals to phoneme engine for testing purposes
    // get the current viseme frame
    OVRLipSync.Frame frame = lipsyncContext.GetCurrentPhonemeFrame();
    if (frame != null) {
      SetVisemeToMorphTarget(frame);
    }
    // TEST visemes by capturing key inputs and sending a signal
    CheckForKeys();
  }
}

マイクで入力させる

キズナアイ(モデル)にOVRLIpSyncMicInputをアタッチします。

そしたら常に音声を認識させられるように、Mic Controlの部分をConstantSpeadkにしておきます。
image.png

もし口の動きが小さくて分かりづらかったら、OVRLipSyncContext > Gainの値をお起きすると口が動きやすくなります。
image.png

これで完成。

まとめ

Viseme To Blend Targetsでマイクから拾ってきた音を認識し、その音声に従ってSkinned Mesh Rendererのモーフが適応されているというイメージかと思います。

もし口が動かない場合は、他のデバイスが音声を拾っていないか、Gainの値が小さすぎないかを確かめていただければと。

53
51
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
53
51