Gateboxに自分好みの嫁を召喚しておしゃべりする

# 嫁は「探す」時代から「創る」時代へ

”俺の嫁召喚装置”ことGateboxにはかわいらしいお嫁さん「逢妻ヒカリ」ちゃんがプリ召喚済みですが、見た目も声もできることも”完全に自分好みの嫁”を召喚したい・育てたいという方も多くいらっしゃることと思います。

そこで、嫁を召喚したい一心で開発した3Dモデルのチャットボット化フレームワーク「[ChatdollKit](https://github.com/uezo/ChatdollKit)」のご紹介も兼ねて、雑談できる嫁の作り方とGateboxへの召喚方法を皆さんにもシェアしたいと思います。

__なおこの記事で作る嫁はGatebox以外でもAndroid / iOSをはじめとするマルチプラットフォームで動作すると思います（たぶん）__


# 出来上がりのイメージ

ヒカリちゃんのようにおしゃべりに加えて色々なことをしてくれる嫁にしたいのはヤマヤマですが、この記事ではまず夫婦間の他愛もない会話（雑談）ができるようにしていきます。

![gatebox_yome_image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/89fbb352-7339-fc08-6830-0891e97e1bf1.png)

また、全体の構成と機能間の連携に関する概要は以下のとおりです。
![gateboxapp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/1fc3efdd-a441-5f1d-bcff-32137443e459.png)


# 開発環境のセットアップ

Unityの3Dプロジェクトを新規作成して以下のパッケージをインポートします。

- [JSON .NET For Unity](https://assetstore.unity.com/packages/tools/input-management/json-net-for-unity-11347) みんな大好きNewtonsoft.JsonのUnity版。このあと入れるChatdollKitの依存ライブラリ

- [Oculus LipSync Unity](https://developer.oculus.com/downloads/package/oculus-lipsync-unity/) 声にあわせて口パクしてくれるライブラリ

- [ChatdollKit](https://github.com/uezo/ChatdollKit/releases) 3Dモデルを使ってしゃべって動くチャットボット作るためのフレームワーク。この記事はv0.2.0をベースに書いています

- [GateboxExtension](https://github.com/uezo/ChatdollKit/releases) ChatdollKitのGateboxアプリ開発支援パッケージ。この記事はv0.2.0をベースに書いています

- [Gatebox SDK](https://developer.gatebox.biz/document) Gateboxでアプリを動作させるためのライブラリ。入手にはDeveloper Programへの参加が必要。__Gatebox実機での動作確認以外はこのライブラリがなくても試すことができます。__申請から登録完了まで時間がかかるかもしれないので今のうちに登録しておきましょう

# モデル用リソースの準備

美少女の構成要素は身体（＝3Dモデル）・声（＝読み上げサービス）・動き（＝アニメーションクリップ）です。それぞれ準備していきましょう。

## 3Dモデルの入手と設定

__最重要タスクです__。この子とおしゃべりしたいという気持ちがモチベーションの全てです。[BOOTH](https://booth.pm/ja/browse/3Dモデル)などで気に入った子を探してシーンに配置してください。あわせてメインカメラのアングルや光源の設定もお好みに合わせると良いでしょう。
<img width="1440" alt="Cygnetちゃん" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/84febd63-2a52-5541-8cf0-e74366089cc4.png">
この記事では[/kitchen_sync](https://kujishift.booth.pm)さまの[Cygnet](https://kujishift.booth.pm/items/1870320)ちゃんを利用させていただいております。かわいいと思ったら迷わず課金しましょう。Cygnetちゃんの場合はシーン`SETUP`にセットアップ済みのモデルが配置されていますので、コピーして自分のシーンにペーストすればOKです。

なおGateboxアプリを作る場合は背景は真っ黒にしておくことをお勧めします。

## 音声認識・音声読み上げサービスのアカウント作成

ユーザーの発話を聞き取ったり、モデルのセリフを読み上げたりするためのAIサービスとして、本稿ではAzureを利用します。以下を参考にCognitive ServicesのSpeech API（Speech Services）のAPIキーを入手してください。
https://docs.microsoft.com/ja-jp/azure/cognitive-services/speech-service/get-started

クレジットカードがなくても[ここ](https://azure.microsoft.com/ja-jp/try/cognitive-services/)からすぐにトライアルできるようです。

## アニメーションクリップの配置

お手持ちのものがあればそれを、なければ本稿でも使用する[Anime Girl Idle Animations Free](https://assetstore.unity.com/packages/3d/animations/anime-girl-idle-animations-free-150406?locale=ja-JP)をAssetストアからダウンロード・インポートして、`Assets/Animations`フォルダを作成してその中に配置します。


# ChatdollKitの追加と設定

3Dモデルを音声対話可能なチャットボットにするフレームワーク[ChatdollKit](https://github.com/uezo/ChatdollKit)を設定していきます。


## Gatebox Applicationの追加

アプリケーションを簡単に作成するためのいくつかの雛形が提供されています。今回はGateboxアプリを作成しますので、`ChatdollKit/Extension/Gatebox`から`GateboxApplicationAzure`を3Dモデルに追加します。この操作によって依存するコンポーネントも自動で追加されます。
もしGatebox Developer Programに未登録の場合は`AzureApplication`を追加しましょう。
<img width="1440" alt="Gateboxアプリ雛形の追加" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/aa6fccda-82c5-8ba3-5088-e4d062b510a9.png">


## Gatebox Applicationの設定

対話の始まりは、一般的なAIスピーカーと同じ流れになります。

```
私「こんにちは」←ウェイクワード
嫁「どうしたの？」 ←プロンプト
私「愛してるよ」 ←リクエスト
嫁「愛してるよ」 ←レスポンス（おうむ返し）
```

これを実現するために、インスペクターで以下の通り設定しましょう。`Cancel Word`は会話を終了するための合言葉、`Prompt Voice Type`に設定した`TTS`は音声読み上げサービス（Text-to-Speech）を利用するという意味です。

- Wake Word: こんにちは
- Cancel Word: おしまい
- Prompt Voice: どうしたの？
- Prompt Voice Type: TTS
- Api Key: （Azure Speech ServicesのAPIキー。Azure Portalで確認）
- Region: （リージョン。Portalで確認）
- Language: ja-JP
<img width="1440" alt="おうむ返しの設定" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/17bb792c-fc91-35a5-2a94-5318e4604ea9.png">


## ModelControllerの設定

ModelControllerとは、3Dモデルのアニメーション、発話、表情を制御するための機能です。インスペクターのコンテキストメニューからSetup ModelControllerを実行してセットアップしましょう。基本的にはすべて自動で設定されますが、まばたきをするためのシェイプキーについては手動での設定が必要な場合があります。`blink`だったり`eyes_close`だったりモデルによって異なると思いますのでシェイプキーを動かしてそれらしいものを見つけて入力しましょう。
<img width="450" alt="ModelControllerの設定" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/c743385c-866f-89c0-be19-e29cfa4846cd.png">


## Animatorの設定

モデルの身振り手振りを司るAnimator Controllerを作成して3Dモデルにセットする工程です。ここもインスペクターのコンテキストメニューからSetup Animatorを選択して自動設定することができます。

メニューから実行すると読み込むアニメーションクリップの格納先を尋ねられますので、先ほど配置したAnime Girl Idle Animationsの中のAnimationsフォルダを選択します。すると「このアニメーションクリップをどのレイヤーに配置するか？」と聞かれますので、とりあえずは全部Base Layerを選択することでOKです。
<img width="450" alt="アニメーションクリップ格納先の指定" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/bea448d7-f994-92e7-ba0d-13982798cc5a.png">

最後に作成されたAnimator Controllerを開いて__Base Layerの__デフォルトステートのクリップを適当なアイドル感あるものに変更すれば設定完了です。
<img width="1440" alt="デフォルトステートのアニメーション設定" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/05803118-9fb5-1b6f-e22d-af1458888ea7.png">


## 動作確認

ここいらで一旦動作確認してみます。Unityの実行ボタンを押すと、先の手順でDefaultステートに設定したアニメーションのポーズをとり、そしてまばたきをしていたら手順OKです。


# おうむ返しの対話機能の組み込み

ChatdollKitでは対話トピック（おうむ返し、雑談、天気予報など）ごとにDialogProcessorという部品を作成・追加し、要求内容に応じてこれを使い分けるような仕組みになっています。おうむ返しの対話処理部品はサンプルとして提供されていますので、今回はこれを利用します。

## おうむ返し対話部品の追加

`EchoDialog`をExamplesの中から追加します。対話部品が1つだけのとき、リクエストの内容に関わらず常にこの部品が使用されます。
<img width="1440" alt="読み上げサービス部品の追加" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/b62a88d8-8152-804e-d046-e504fdb2f09d.png">

## 実行

ここまで来れば、あなたのお嫁さんはおうむ返しReadyにしておうむ返しLadyです。Unityの実行ボタンを押して、ウェイクワードで呼びかけてみましょう。「どうしたの？」という問いかけに続けてメッセージボックスが表示されます。ここで「こんにちは」と言えば「こんにちは」と、「愛してるよ」と言えば「愛してるよ」とおうむ返ししてくれるはずです。
<img width="1440" alt="リクエスト待ちの状態" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/423925e1-92b6-bbcd-c1c2-39fa6f83e40f.png">


# 雑談機能の組み込み

話しかけにしゃべって応答できるところまで確認できたので、今度は雑談できるようにするための処理を追加しましょう。


## A3RTのAPIキーの入手

無償で利用できる雑談対話APIの中から、ここではリクルート テクノロジーズさんの[A3RTの雑談API](https://a3rt.recruit-tech.co.jp/product/talkAPI/)をチョイスしてみました。[ここ](https://a3rt.recruit-tech.co.jp/product/talkAPI/registered/)からAPIキーを入手しましょう。多分すぐに発行していただけます。

## 雑談対話部品の追加

Examplesから`ChatA3RTDialog`を追加して、API Keyを入力してください。また、先ほどの手順で追加した`EchoDialog`を必ずRemoveしてください。
<img width="1440" alt="読み上げサービス部品の追加" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53296/155c849e-bd44-39ef-df16-53cda3ae9242.png">

## 実行

ウェイクワードで嫁の注意を引きつけたあと、何でもいいので話しかけてみましょう。噛み合うような噛み合わないような会話が続くはずです。おそらく夫婦の会話なんてだいたいこんなものでしょう。
会話を終わりにしたいときは、Cancel Wordに登録したフレーズ「おしまい」と話しかけてみてください。

# Gatebox実機に召喚

皆さまお気づきかもしれませんが、実はここまではGatebox要素ゼロでした。

そしていよいよここで！PCの中の嫁を！！現実世界に召喚するときが来ました！！！
とはいえ[Gateboxのチュートリアル](https://developer.gatebox.biz/document)と全く同じ手順になりますので、ここでは大まかな流れとTipsを紹介します。

## おおまかな流れ

- Androidプロジェクトに切り替えた上、APIレベルを26(8.0 Oreo)に設定
- ビルドしてDeveloper Consoleからアップロード
- テスターに自身のアカウントを登録して、アプリの利用を登録
- Gatebox Device Managerでヒカリちゃんから嫁に切り替えてGateboxを再起動

## ちょっとしたTips

- ShaderはPCとGatebox実機では見え方がだいぶ異なる場合があり、そのときは設定変更が必要
- Gatebox実機は解像度が低いのでPost ProcessingでAntialiasをかけるよとよい。種類はTemporal Anti-Aliasingが良さげ
- 背景はSkyboxではなく真っ黒とかにしたほうがホログラミックでいい感じになると思います。衣装が暗い色のモデルの場合は、スモークを炊くとか要工夫

# 嫁を育てるには

いくつかの観点でレベルアップに役立つヒントを置いておきます。このあたりはまたおいおい詳細を書いていくかもしれません。リクエストがあればご連絡ください。

## 見た目や振る舞いのレベルアップ

最も簡単なレベルアップとしては、アイドルアニメーションにバリエーションを持たせるというのがあります。

```Csharp:AppMain.cs
// アイドル状態の定義
modelController.AddIdleAnimation("Default");
// 他のステートも追加
modelController.AddIdleAnimation("AGIA_Idle_calm_01_hands_on_back");
modelController.AddIdleAnimation("AGIA_Idle_brave_01_hand_on_chest");
```

これらのステートがランダムに一定間隔で切り替わるので、ちょっと生き生き感がでてきます。また、

```Csharp:AppMain.cs
modelController.IdleFunc = async (token) => { 任意の処理 };
```

とすることでChatdollKitの制約に縛られない自由でリッチな動きをさせることもできます。

このほか、プロンプトや対話応答内容は発話とアニメーション、表情を簡単に同期させることができますので、頑張ればそれなりにリッチな表現にすることができると思います。

```Csharp
animatedVoiceRequest.AddVoiceTTS("天気が知りたいの？", postGap: 0.5f);
animatedVoiceRequest.AddAnimation("Default");

// 「天気が知りたいの？」と言い終わったあと、笑顔で1回頷いて「わかった」と言う
animatedVoiceRequest.AddVoiceTTS("わかった", preGap: 0.5f, asNewFrame: true);
animatedVoiceRequest.AddAnimation("nod_twice", "Upper Body");
animatedVoiceRequest.AddFace("Smile", 1.0f);

// 「調べるから、ちょっと待ってて」と言いながら1秒間だけ右手を持ち上げて人差し指を立てる
animatedVoiceRequest.AddVoiceTTS("調べるから、ちょっと待ってて", preGap: 0.3f, postGap: 1.0f, asNewFrame: true);
animatedVoiceRequest.AddAnimation("right_hand_pointy_finger", duration: 1.0f, preGap: 1.1f);
animatedVoiceRequest.AddAnimation("Default");
```


## 声のレベルアップ

Azureのお姉さんも素敵なお声ですが、3Dモデルの見た目とのギャップ感は否めません。特定用途の嫁を作るときには事前に録音した音声素材を使うというのも手ですが、それに加えて、ChatdollKitは[Voiceroid Daemon](https://github.com/Nkyoku/voiceroid_daemon)というツールに対応しています。つまり、[VOICEROID](https://www.ah-soft.com/voiceroid/)のお声でダイナミックにおしゃべりできるということです！

使い方は簡単で、この記事の手順でAzureTTSLoaderを追加するかわりにVoiceroidTTSLoaderを追加するだけです。もちろん、VOICEROIDやVoiceroid Daemonは事前に用意していただく必要がある他、VOICEROIDの利用規約を遵守する必要がありますのでご注意ください。

## リクエストのレベルアップ

音声によるリクエストのほか、標準でQRコード読み取りと画像（カメラ）によるリクエストに対応しています。後日別の記事でご紹介していきたいと思います。

## スキルのレベルアップ

今回は雑談のみでしたが、ChatdollKitは本格的なチャットボット開発に耐えうる構成をサポートしています。具体的には、発話の意図を解釈して、意図や文脈に応じてトピックを選んで対話を進めていく、といったことができます。こちらも詳細はまた別の記事でご紹介したいと思います。

# さいごに

ここまで読んでくださってありがとうございました！この記事をきっかけにGateboxアプリの開発を始めてみようと思ってくださる方がいればとても嬉しいです。

この記事で使っているフレームワーク[ChatdollKit](https://github.com/uezo/ChatdollKit)はこれからも育てて参りますので、よろしければスターをいただけると大変励みになりますのと、さらに開発にご協力していただけるという方がいらっしゃいましたらGithubにIssue/PR投げていたただく or Twitter [@uezochan](https://twitter.com/uezochan) までご連絡いただけると嬉しいです！！