【Unity】OVRLipsyncで小春六花ちゃんに喋ってもらう

先日、合成音声ソフト「CeVIO AI」の新作である「[CeVIO AI 小春六花 トークボイス](https://www.ah-soft.com/cevio/rikka/index.html)」が発売されました。
早速購入したところ、3Dモデルもついており、せっかくなのでUnityで口パク付きで喋ってもらうことにしました。

# 音声準備
![rikka.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/938939/2686b320-4522-fe89-7587-76abe2338682.png)

**CeVIO AIトークエディタ**で音声を作成します。
CeVIO AIは初めてですが、イントネーションの設定や感情の設定などインターフェースが分かりやすくて直感的に操作できます。
まだ全部を試してはいませんが、Voiceroidよりもできることは多そうですね。
今回は特にチューニングせず、簡単に音声を作成して.wavで出力しました。

# モデル用意
同梱されていた3DモデルはMMDのため、Unity内で**MMD4Mechanim**を使って、FBX形式に変換しました。
- [MMD4Mecanimの使い方等](https://qiita.com/hiroyuki_hon/items/931c79164b0ffe19517f)

# OVRLipsync(口パク実装)
OVRLipsyncはOculusが出しているリップシンク用パッケージです。今回行う音声データに基づいたリップシンクの他、マイク入力音声からリップシンク、笑い声の検出を行うこともできます。
## OVRLipsync導入
[OVRLipsyncダウンロードページ](https://developer.oculus.com/downloads/package/oculus-lipsync-unity/)からzipファイルをダウンロードします。
zipファイル内の`OculusLipSync.unitypackage`をUnityにインポートするだけで導入は完了です。
## コンポーネントの取り付け
1. 空のオブジェクトを作成し、`OVRLipSync`を取り付けます。
2. 空間上にリップシンクを行う3Dモデルを配置し、`OVRLipSyncContext`と`OVRLipSyncContextMorphTarget`を取り付けてください。
  - この時AudioSourceが自動で取り付けられます。

## リップシンクの設定
リップシンクの設定は3Dモデルに取り付けた`OVRLipSyncContextMorphTarget`で行います。
![blendshape設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/938939/12af5ace-a9e7-ec11-6b9a-df58e5ea4d61.png)

- `スキンメッシュレンダラー`に**顔部分のメッシュを選択**します。
  - 画像右のようにインスペクタに`BlendShapes`が表示されるオブジェクトが顔部分のメッシュです。
![顔mesh見つける.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/938939/3cfa270d-56a5-02da-7c6a-7983734cb1a2.png)
- `Viseme To Blend Targets`には15種類の[口形素](https://developer.oculus.com/documentation/unity/audio-ovrlipsync-viseme-reference/)が定義されています。そして、それぞれの口形素に**BlendShapesのインデックス**を対応付けすることでリップシンクが行えます。
  - 例）`Viseme To Blend Targetsの要素10`に0と入れた状態で、「あ」と発音した場合、「あ」の口形素である`Viseme To Blend Targetsの要素10`に対応付けた、インデックス0のBlendShapes(**0.あ**)が動きます。
  - 設定項目は15個ありますが、それぞれどのような発音、口の動きを想定しているかは[公式リファレンス](https://developer.oculus.com/documentation/unity/audio-ovrlipsync-viseme-reference/)や[VRChat Wiki](https://vrchatjp.playing.wiki/d/%A5%A2%A5%D0%A5%BF%A1%BC%A4%CE%A5%EA%A5%C3%A5%D7%A5%B7%A5%F3%A5%AF%A4%CE%BA%EE%C0%AE)を覗いてみてください。
- 今回は母音のみ対応付けました。

|Viseme To Blend Targets  |BlendShapesインデックス  |
|---|---|
|要素10  |0 (0.あ) |
|要素11  |3 (3.え) |
|要素12  |1 (1.い) |
|要素13  |4 (4.お) |
|要素14  |2 (2.う) |
![スクリーンショット 2021-03-24 221402.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/938939/bf687953-8d3e-cfb3-c135-42de98693da0.png)

# 音声の設定
- 冒頭の音声準備で作成した音声wavファイルをunityにインポートします。
- 3Dモデルに取り付けられているAudioSource(OVRLipSyncContextを取り付けた際に自動で追加されます)の`オーディオクリップ`にインポートした音声ファイルを取り付けます。
- `OVRLipSyncContext`の`Audio Loopback`にチェックを入れます。

# 結果
<iframe width="560" height="315" src="https://www.youtube.com/embed/xSunvTqLXh0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

特にコーディングなしでリップシンクができるのは手軽でいいですね！
(口の広がりが足りないときは`OVRLipSyncContext`の`Gain`を大きくしてみてください(デフォルト: 1))
(あとはCevio AIでリアルタイムに文字読み上げとかできればAI Vtuberとかできそうで面白そう。。。)

# 参考
- https://vrchatjp.playing.wiki/d/%A5%A2%A5%D0%A5%BF%A1%BC%A4%CE%A5%EA%A5%C3%A5%D7%A5%B7%A5%F3%A5%AF%A4%CE%BA%EE%C0%AE
- https://developer.oculus.com/documentation/unity/audio-ovrlipsync-viseme-reference/