Unity + MMD (3D邪神ちゃん) + ChatGPT (OpenAI API) + VOICEPEAKで「邪神ちゃんエーアイ!」というアプリを作りました。邪神ちゃんに関する事をAIに聞いて、それを邪神ちゃん(VOICEPEAK)に突っ込ませるという貴族の遊びです。邪神ちゃんしか出てきません。
開発
下準備
開発に取り掛かるため、以下の準備をしておきます。
- Unityのインストール
- パッケージマネージャーでBurst Compilerを導入
- UniTaskの導入
- OpenAI APIのアカウント作成とAPIキーの取得
- APIキー取得後、クレジットカードの支払い登録で無料枠5ドル(3か月限定)がもらえます
- VOICEPEAK 邪神ちゃんのインストール
- 無料お試し版の場合、必ず専用のURLからダウンロード (通常の体験版と別プログラムのため)
UnityとChatGPTの連携
APIとの連携用クラス
APIを叩いてChatGPTとメッセージをやり取りする部分は、ねぎぽよしさんの ChatGPTConnectionクラス を利用させていただきました(詳細はリンク先を参照)。なお、このクラス内でUniTaskが使われています。
クラスの呼び出し側で、あらかじめChatGPTConnectionのインスタンスを生成した上(e.g. MonoBehavior継承クラスであればStartメソッド内)で、引数に質問を入れてRequestAsyncメソッドを呼び出すことで非同期処理によりChatGPTからの回答が得られます。また、元のクラスでは外部からの性格付けができないため、コンストラクタからプロンプト(人格注入用の設定)を入れられるようにしました。
プロンプト生成
独自のC#スクリプト「ChatGPTJashin」を組みました。
機能は、単純に前述のクラスを用いたChatGPT APIとの通信(質問・設定の送信+回答の受信)とプロンプトの生成です。最大の特徴は、このプロンプトが柔軟に変えられる仕様で、インスペクタのパラメータ入力欄で邪神ちゃんのみならず、様々なキャラクターが表現可能です。
性格設定のパラメータは以下の通り。
- Character:キャラクター名
- (First/Second)person:一/二人称
- Personality:性格。一文で性格を表す単語を入れる(e.g. 邪神ちゃんなら "selfish, greedy, scum and foolish")
- Numletter:回答の文字数制限
- Endings:語尾(配列)
- Phrases:よく言うセリフ(配列)
- Supplements:補足(配列)
以上のパラメータを含めた人格設定の文字列Contextを、ChatGPT APIで送ることでAIキャラの性格を設定します。プロンプトの設定やテンプレートはChatGPT用キャラ口調設定Wikiを参考にしました。ちなみに、プロンプトは日本語でも使えるかもしれませんが、英語の方が精度が高い気がします。
キャラクター描写
3Dモデル
公式の3DモデルがMMDモデルなので、Unityで利用できる形に変換するため MMD4Mecanim を使います。変換が無事に終わったらUnityのシーンに入れてみましょう。画面に表示されたらひとまず成功。
口パク
話すと同時に口パクもさせたいので、リップシンクも導入します。今回は凹みさん開発の uLypSync にしました。内部でJob SystemとBurst Compilerが使われているので、Burst Compilerを有効にしておきます。リンク先を参照しながら3Dモデルに必要なコンポーネント(ULipSync、ULipSyncBlendShape、AudioSource)を割り当て、AudioSourceで音声を流すことで3Dモデルが口パクします。
合成音声
こちらのnote記事(とりにくさん)をもとに、邪神ちゃんの合成音声を生成するスクリプトを開発しました。
VOICEPEAKのコマンド引数
VOICEPEAKには連携用のAPIなどは用意されておらず、基本的には外部アプリとの連携ができません。しかしVOICEPEAKには、コマンドプロンプトから実行する際に入れられる隠しコマンド(引数)があり、無料版では outpath (出力先パス)、narrator (声の種類。邪神ちゃん版は1種類のみなので使用不可)、Message (話す内容)を指定でき、wav形式の音声を生成できます(有料版になれば感情設定の項目もあるらしいので、表現の幅がより豊かになりそう)。
そこで、上記URLの様にUnityからコマンドプロンプト経由でVOICEPEAKを実行することで、Unityから合成音声を生成できるようにします。
C#からの外部実行
C#には別プログラムをコマンド実行するためのSgnostics.Processクラスがあるため、VOICEPEAKをProcessから引数付きで実行することで、ChatGPTからの回答を音声に変換します。
音声生成の処理に加え、プロジェクト内にインポートすることでAudioClipへの自動変換も働くので、動作は割と遅いです。そのため、VOICEPEAKの終了をProcess.Exitedイベントで待ち、終了後の処理に音声再生を割り当てることで、システムが確実に声を発するようにします。なお、音声再生やUI処理はUnityメインスレッドで実行される必要があるため、SynchronizationContextを握ってそこに終了後の処理を投げます(SynchronizationContext.Postメソッド)。
UI
あとは、質問の入力欄とChatGPTに送信するためのボタン、回答表示のテキスト欄といったUIを画面に設置し、必要なイベント処理を割り当てました。また、邪神ちゃんゴシックという素敵すぎるフォントもあったので一緒に採用しました(公式も使うくらいの完成度!)。
補足
- 費用をケチる為、VOICEPEAKおよびChatGPTは無料版を使いました。(GPT4だとおそらく回答精度も向上し、VOICEPEAKもより感情豊かに喋れます。)
- 一部、ChatGPT側の回答を編集しています(省略・連結)
- AI側で一部表記や読み方がおかしな部分があります。