Unityからゆかりさんをしゃべらせて、口パクをコントロールする

長年やりたかったことが実現しましたので、忘備録として、記事にしてみました。

下準備(インストール編)

下準備(棒読みちゃん設定編)

VOICEROIDとの連携設定については、こんな感じです。詳しくはVoiceroidTalkPlusのページから確認してみてください。

棒読みちゃんでは、クリップボードを監視して、テキストがコピーされたときにVOICEROID+へテキストデータを送信するためのパイプ役になります。あらかじめ次の設定をしておきます。

クリップボード監視の有効をONに、配信者向け機能を有効に、自動スキップ機能を有効に、スキップ開始文字数を1にする

クリップボード監視の有効をONにしておきます。また、配信者向け機能を有効にします。

設定から自動スキップ機能を有効に、スキップ開始文字数を1にします。クリップボード読み上げを有効にしていると、よく棒読みちゃんが暴走して同じフレーズを繰り返し再生するため、
この設定をすることである程度防ぐことができます。ただ、クリップボードの拾いこぼしも起きやすくなります。

下準備(VOICEROID、サウンド設定編)

VOICEROIDでは、NETDUETTO βで追加された音源ラインの設定をします。

音声出力デバイスをライン(Yamaha NETDUETTO Driver ((WDM))に変更する

VOICEROID Editorのメニューから、 設定 > 音声出力設定を選びます。

音声出力デバイスをライン(Yamaha NETDUETTO Driver ((WDM))に変更します。

使用できる録音可能デバイスをライン(Yamaha NETDUETTO Driver ((WDM))のみにする。

他の録音デバイスを無効にし、使用できる録音可能デバイスをライン(Yamaha NETDUETTO Driver ((WDM))のみにします。こうする理由は、ライン入力の場合、録音の既定デバイスに設定できず、Unity側で音声を拾えないためです。


また、この方法ではスピーカー出力に紐付けされないため、音が出ません。なので、録音可能デバイスのほうのライン(Yamaha NETDUETTO Driver ((WDM))を右クリックし、プロパティから、このデバイスを聴く、のチェックボックスをONにして、スピーカーから聞こえるようにしておきます。

テキストボードにコピーするスクリプトを用意する

ここのサイトを参考に、
下記のようにヘルパースクリプトを作成します。(保存するときの名前:ClipboardHelper)


using UnityEngine;
using System;
using System.Reflection;

public class ClipboardHelper
{
private static PropertyInfo m_systemCopyBufferProperty = null;
private static PropertyInfo GetSystemCopyBufferProperty()
{
if (m_systemCopyBufferProperty == null)
{
Type T = typeof(GUIUtility);
m_systemCopyBufferProperty = T.GetProperty(“systemCopyBuffer”, BindingFlags.Static | BindingFlags.NonPublic);
if (m_systemCopyBufferProperty == null)
throw new Exception(“Can’t access internal member ‘GUIUtility.systemCopyBuffer’ it may have been removed / renamed”);
}
return m_systemCopyBufferProperty;
}
public static string clipBoard
{
get
{
PropertyInfo P = GetSystemCopyBufferProperty();
return (string)P.GetValue(null,null);
}
set
{
PropertyInfo P = GetSystemCopyBufferProperty();
P.SetValue(null,value,null);
}
}
}

また、ClipboardHelperを使用した制御用スクリプトを作成します。(保存名:ClipBoardTest)
長い文章を読ませるときは、delayTimeを長めに設定してみてください。


using UnityEngine;
using System.Collections;

public class ClipBoardTest : MonoBehaviour {
int cnt = 0;
float time = 0f;

public string[] messages = {“こんにちは”, “結月ゆかり”, “です”};
public float delayTime = 3.0f;

// Use this for initialization
void Start () {
//ClipboardHelper.clipBoard = “こんばんは、結月ゆかりです”;
}

// Update is called once per frame
void Update () {
time += Time.deltaTime;
if (time > delayTime) {
time -= delayTime;
ClipboardHelper.clipBoard = messages[cnt];
cnt = (cnt + 1)%messages.Length;
}
}
}

適当なGameObjectにClipBoardTestを追加します。依存関係はないので、シーンにあらかじめ用意されているMain Cameraなどに追加しておくと良いかもしれません。その後実行し、UnityからVOICEROIDのコントロールができるか試します。

MMD4Mecanimでモデルを用意し、MMDのGameObjectにMMD4Mecanim LipSync Pluginを追加する

NoraさんのHPからMMD4Mecanim 【Stereoarts Homepage】 をダウンロードして、
モデルとあわせてUnityへの導入をしておきます。この辺の説明は割愛させてもらいます。

次に、凹みさんのサイトから、MMD4Mecanim LipSync Plugin 【Unity でリアルタイムにリップシンクする MMD4Mecanim LipSync Plugin を作ってみた】 を導入します。凹みさん、いろいろアドバイスいただき、ありがとうございました!

MMD4M_LipSync(LipSyncフォルダ内)のスクリプトをゆかりさんのMMDモデルが適用されたGameObjectに追加します。

Callibrationのために、VOICEROIDからゆかりさんの声で、「あ」、「い」、「う」、「え」、「お」、のみを発声した、それぞれ1秒程度のwavファイルをVOICEROIDから適当に出力しておきます。「ああああ」とか「いいいい」とか繋げて発声させているファイルのほうが良さそうです。 イントネーションは山の形にしておくと良い?(未検証)

UnityにインポートしてMMD4M_LipSyncのCallibrationタブ内に設定します。

Microphoneタブ内のUse MicのチェックをONにして、A、I、U、E、Oの箇所にそれぞれのwavファイルを設定します。

設定が終わったら、Callibrationボタンを押してゆかりさんの声に最適化します。また、たまに「い」の発音しか認識しなくなる時があり、(原因が不明なので、合ってないかもしれませんが)その場合は一度Use MeiChan’s default parametersを押して、再度Callibrationボタンを押すとうまくいきました。
ついでにLip Sync Delay Timeを0.1から0.05あたりに変えておきます。ここの数値が小さいほど口パクの口の形がタイトになります。歌とかの場合はこの数値を大きめにしておくと幸せになれそうです。

実行してみる

あとは実行するだけです。実行例はTwitterにおいています。