お手軽にAlexaスキルと Unity を連携させる (VoiceFlow)

Alexaスキルは、ノンコーディングで作れるサービスが多数あるので サクっと作成できます。

さらに Unity と連携させると、、、
 **「Alexa、ダンスを開始して」で、ユニティちゃんが踊りだす** みたいなのが簡単に作れます。

ということで、お手軽にAlexaスキルと Unityを連携する方法をまとめました。

#Alexaスキル作成サービス
<img width="1358" alt="スクリーンショット 2020-02-14 18.34.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/3e11993d-f783-ee65-4553-cb655c65eb90.png">
無料で始められる [VoiceFlow](https://www.voiceflow.com/) を使います。

他にもたくさんサービスがありますが、VoiceFlow は多機能で使いやすいUIが魅力です。
比較的新しのでたまにおかしな挙動もありますが、アップデートで徐々に改善されてきています。

# Unityで WebAPI を準備する
Alexa には WebAPI と連携する機能があるので、まず Unityで WebAPIを作ります。

###HTTPサーバーを作成する
下記の Unity HTTPサーバーを作成し、再生しておきます。
[前回記事：UnityでマルチスレッドなHTTPサーバー](https://qiita.com/fukusin/items/61247231e0d97841ac9b)

GetDataというリクエストがきたら、MyDataの値を返す。
SetDataというリクエストがきたら、MyDataの値を変更して、値を返す。 
という簡単なAPIです。

###HTTPサーバーを外部公開する
Alexaスキルは、内部サーバーとは通信できない仕様なので、[ngrok](https://ngrok.com/) などで外部公開させておきます。
[参考：【3分で出来る】ngrokでデプロイをしてみよう！](https://qiita.com/derorian3/items/5ab961c1d5cff5f50141)

ngrokは 起動するたびに URLがランダムに変わってしまうので、有料プランで固定ドメインにすると楽ちんです。
[参考：ngrokのドメイン名を固定した時の「Bad Request」エラーを回避する](https://qiita.com/fukusin/items/f898c1e06d43b674e753)

# VoiceFlow で Alexaスキルを作る
VoiceFlow は、Integration Block でカスタムAPI連携ができるので、これを使います。
適当なプロジェクトを作って、Unity からのレスポンスを取得できるか試します。

###Integration Block でレスポンスを取得する
Integration Blockを配置し、Start からラインを繋げます。
<img width="910" alt="スクリーンショット 2020-02-14 19.03.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/bbc6c634-7d5e-8c07-f8c4-2f17536ab585.png">

Integration Block を選択し、Custom API を選びます。
リクエスト内容は下記のように設定します。
Request URL には、上で設定した外部公開サーバーのURLを指定してください。
<img width="992" alt="スクリーンショット 2020-02-14 19.14.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/df256703-da5f-b1ae-5813-5a24e297642a.png">

GetDataリクエストの場合、Params の Value は空でもいいはずなのですが、何故か テスト時にレスポンスが返ってこないので、適当に何か入れておきます。

Test Request を押すと Unity からのレスポンスを確認できます。
<img width="851" alt="スクリーンショット 2020-02-14 19.22.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/65ac0658-a0c8-762a-d1b7-ee0c6ab58870.png">

MyData クラス の success の値が返ってきました。

ちなみに success の横のクリップボードを押すと、変数の参照をコピーできます。
Alexaスキル内 の変数として格納したい時に使います。
<img width="971" alt="スクリーンショット 2020-02-14 19.30.11.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/c186ad4b-05f1-5bef-9631-9fbd02e23447.png">

###Integration Block で値を送る
次にParams を変更して SetData リクエストを送ってみます。
<img width="959" alt="スクリーンショット 2020-02-14 19.38.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/604332d7-8858-1bd4-d1d9-e028d94ac692.png">
<img width="477" alt="スクリーンショット 2020-02-14 19.48.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/482cef8a-bf2d-153f-6278-623e9ce7afc0.png">
ちゃんと Unity に届きました。

# 会話を作りこむ
ここからは Unity 連携と関係なくなってくるので、割愛します。
VoiceFlow は簡単に会話を作れるので、好きに作りこんでみてください。

いちおう、こんな感じのが作れます。

1. スキルが開始されると Success の値を確認
2. イエスなら値を変更、ノーなら会話終了
3. 変更内容を伝える
<img width="1233" alt="スクリーンショット 2020-02-14 20.19.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/ca8cf0d3-79ad-9f1c-b04d-2da508ac6883.png">

####Alexa の会話で 変数の値を使うには
 ```{success}``` のように  \{\} で囲います。
<img width="852" alt="スクリーンショット 2020-02-14 20.33.20.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/b8d4d87f-ef69-5706-4d85-170fb94790e9.png">

####if blockで 変数の分岐をする場合は
右辺のタイプをExpressionにします。
<img width="757" alt="スクリーンショット 2020-02-14 20.47.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/0c74e93b-d29e-b490-c172-a81b3a26a1b2.png">


####Alexa スキル の テスト
Prototype タブに切り替えると PC上でテストできます。
<img width="898" alt="スクリーンショット 2020-02-14 20.32.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/34545e95-9ea0-bfc0-b1de-39e3a716bea2.png">

Start Test を押すとチャットで会話がはじまります。
<img width="400" alt="スクリーンショット 2020-02-14 20.32.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535406/9b8971e1-8ff0-0724-3901-9779efa57c38.png">
味気ないですが、一応会話らしきもので Unity と連携できました。

Alexaデバイスとリンクしてビルドすれば、ちゃんと会話してくれます。