読者です 読者をやめる 読者になる 読者になる

UnityからCortanaの機能を使うサンプルプロジェクトを調べてみました

Unity UWP HoloLens

一通り目処がつきましたので紹介します。

以前、下記の記事でCortanaとUnityを連携させる方法を調べました。

magicbullet.hatenablog.jp

今回、ここで紹介した2種類のサンプルのうち、(1)を使う方法を解説します。

※(2)は未調査です。


目次

1. 前提

1-1. サンプルソリューションの概要

1-2. サンプルソリューションの制限事項

2. 確認手順

2-1. Unityでビルド

2-2. Visual Studio側でCortanaを使うために設定

2-3. Deploy

2-4. 動作確認

3. Tips

4. 終わりに

1.前提

1-1. サンプルソリューションの概要

前回も紹介した通り、下記ブログで紹介されているサンプルを使います。
ブログの末尾でプロジェクト一式をダウンロードできます。

Voice Activating your Windows 10 games using Speech Synthesis, Voice Recognition and Cortana | digitalerr0r

このサンプルでは、Unityで作られた近未来的な建物の部屋の中からスタートします。

f:id:Takyu:20160702133400p:plain

画像の右側がスタート地点、左側に大きな眼をしたロボット?がいます。

PlayerはFPSControllerのPrefabです。キーボードまたはゲームパッドでロボットの近くまで移動すると、このようにテキストが出現します。

f:id:Takyu:20160702133603j:plain

ここには、

What is your name?

What do you do here?

Forecast

と書かれています。Windows10デバイスでこれのUWPを実行してれば、この状態の時に3つのどれかの言葉を発声すると、Cortanaが返答してくれます。

上記3つの質問文、および各質問に対する回答は、Unity側のリスト配列で定義されており、任意の言葉に変更可能です。

f:id:Takyu:20160702133848p:plain


このサンプルでは、ロボットにSphereColliderが取り付けられ、OnCollisionEnterでPlayerが範囲内に近づいた時だけ先ほどのメッセージを表示し、音声の入力待ちになります。

f:id:Takyu:20160702134104j:plain

1-2. サンプルソリューションの制限事項


このサンプルは、

[1]UWPアプリを実行するPCまたはスマートフォンで、キーボードまたはゲームパッドが動くこと

[2]PCまたはスマートフォンの言語と地域がen-USになっていること

という条件を満たさないと動作確認ができません。

手持ちのデバイスには、Windows 10 Mobile(KATANA01)と、Windows10 Proがありましたが、どちらも動作確認できませんでした。


[KATANA01]

en-US設定にはできたが、Bluetoothキーボードがなく、実行時に移動ができなかった


[Windows10 Pro]

実行時に移動はできたが、地域設定をen-USにしたらCortanaが使えなくなってしまった

f:id:Takyu:20160618153620p:plain


上記いずれかを回避できれば、サンプルをそのまま動かすことはできます。

今回は、サンプル動作確認のため、常に音声の入力待ちになるようにUnity側を変更し、再ビルドする手順を紹介します。

2. 確認手順

2-1. Unityでビルド


まずは先ほど紹介したブログより、サンプルを入手します。BotWorld.zipとPlugin.Windows10.Cortana.zipの二種類が入手できます。

[BotWorld.zip]

今回の動作確認に必要なものがすべて入ったソリューション一式です。

[Plugin.Windows10.Cortana.zip]

自分で任意のCortana-Unity連携アプリを作りたいときのセットです。BotWorld.zipにも同じものが入っています。



今回はBotWorld.zipだけを使います。zip解凍後、BotWorldフォルダを指定してUnityで開きます。
本来Unity5.2で作られているようですが、Unity5.3.5f1およびUnity5.4.0b14-HTPのどちらでも動きました。

Unityで開いたら、GameObject / Create Emptyで空のGameObjectを作ります。ProjectViewで新規ソースファイルを作り、下記のCortanaController.csをコピペしたら、CortanaControllerのオブジェクトにアタッチします。


gist9826fff1db7559b2ead7ba574ce75328


続いて、CortanaControllerのInspector Viewを開き、下記のように好きな質問文と回答文を入力します。
(サンプルのVoiceBot.csのスクショですが、CortanaController.csとpublicの宣言は同一です)

f:id:Takyu:20160702133848p:plain

また、Bot UI PanelとQuestion Optionsには、Hierarchy ViewのCanvas1とCanvas1/Panel/Textを指定します。

ここまで出来たら、ビルドします。ビルド設定は下記の通りです。

f:id:Takyu:20160702142237p:plain

まず、Switch PlatformでWindows Storeにします。続いて、

SDK Windows 10
UWP Build Type XAML
Build and Run on Local Machine
Unity C# Projects チェックをつける

と設定します。

[補足1]

Build TypeはXAMLにしてください。D3Dにすると、その後の設定でCortanaの制御ができなくなります。

[補足2]

Build TypeをBuild and Run onには、Windows Phoneというオプションもあります。しかし、Local Machineにしておいても、あとでWindows 10 MobileにDeployできました。

[補足3]

HoloLensの場合、Virtual Reality Supportedにチェックを入れると、全天周のアプリになります。VR系アプリを作っている方は想像しやすいと思いますが、CG空間の一部だけがレンダリングされ、センサの向きによって表示される内容が変わるものです。

チェックを入れないと、普通のUWPアプリと同一の扱いになり、空間に張り付けることができます。


[補足4]

Unity5.4.0b14-HTPでVirtual Reality Supportedにチェックをつけてから作ったC#プロジェクトを、Visual StudioでWindows10 Mobile用のUWPにしたところ、問題なく動きました。


その後、UnityからBuildを実行し、ビルド結果の保存先をEXPORTフォルダにします。

(注意)
2回目以降に試す場合は、BotWorldのフォルダにあるEXPORTフォルダの中身のうち、BotWorldVoiceCommandServiceとPlugin.Windows10.Cortanaフォルダ以外のすべてを削除しておいた方が、変な不具合が起きなくて安心です。


f:id:Takyu:20160702143138p:plain




2-2. Visual Studio側でCortanaを使うために設定

まずはVisual Studioで、BotWorld/EXPORT/CortanaWorld.slnを指定します。

この後、やることが色々あるので順番に説明します。

2-2-1. 2つのプロジェクトを追加


CortanaWorld.slnは、3つプロジェクトを束ねて使うのですが、初期状態では1つしか認識されていません。

f:id:Takyu:20160702150553p:plain

そこで、残り2つを認識させてこのようにします。

f:id:Takyu:20160702150608j:plain

プロジェクトを追加するには、Solution Explorerで先頭のSolution "CortanaWorld"で右クリックし、Add/ Existing Project..を選択します。

f:id:Takyu:20160702151340p:plain

追加対象は、BotWorldフォルダにある、BotWorldVoiceCommandServiceとPlugin.Windows10.Cortanaの2つです。

f:id:Takyu:20160702151436p:plain

このようにcsprojファイルを指定します。Plugin.Windows10.Cortanaの場合も同様です。


(注)
自分で0からUnityプロジェクトを作っていくと、2-1を終えてslnを開いたとき、

Assembly-CSharp

Assembly-Sharp-firstpass

というプロジェクトが追加され、合計5つになりました。理由は不明です。

f:id:Takyu:20160702151558p:plain

ちなみに、Assembly-CSharp側には、Unityで作ったスクリプトが入っており、ここで変更したものはUWPのDeployに反映されます。(Public変数の変更は無理だと思いますが)

2016/7/5追記

上記二つが追加される要因がわかりました。UnityでBuild Settingsを開いたとき、Unity C# Projectsにチェックをつけていると追加されます。
実は今回のようにUnity→Cortanaにデータを渡すだけの処理であればUnity C# Projectsのチェックは不要です。
ただし、Cortana→Unityにデータを渡したいときや、Visual StudioでUnity のビルド結果を修正したいときは必要になります。

2-2-2. Add Referenceを設定

続いて、3つのプロジェクトが相互に参照できるように設定します。

Solution ExplorerでCortanaWorldを右クリックし、Add Referenceを選択します。

f:id:Takyu:20160702151833p:plain

BotWorldVoiceCommandServiceと、Plugin.Windows10.Speechにチェックをつけ、OKを選択します。

f:id:Takyu:20160702152039p:plain


2-2-3. Restore Nugetの設定

Solution ExplorerからApp.xaml.csかMain.xaml.csを開きます。すると、このように大量のエラーがでます。

f:id:Takyu:20160702152214p:plain

原因は管理ライブラリが壊れているためです。なぜか毎回こうなるので、Restore Nuget Packagesで復元します。

f:id:Takyu:20160702152405p:plain


(以後、参考にさせていただいたブログと同一の手順のため、画像を引用しました)

2-2-4. Package.appxmanifestの修正

マニフェストファイルを選択し、

f:id:Takyu:20160702153018p:plain

ServiceとしてApp Serviceを追加します。

f:id:Takyu:20160702153115p:plain

このように、NameとEntryPointを追加します。

f:id:Takyu:20160702153140p:plain

また、Capabilitiesにて、Internet(Client)と、Microphoneを指定します。

f:id:Takyu:20160702154012p:plain

2-2-5. MainPage.xamlの修正

下記のように

<MediaElement x:Name=”Media”></MediaElement>


を追加します。

(上記は、"<"と">"が全角になっているので、半角に修正して使用ください)

f:id:Takyu:20160702153248p:plain

2-2-6. MainPage.xaml.csの修正

OnNavigatedToメソッドの指定箇所に

Plugin.Windows10.VoiceSpeech.Media = Media;
Windows10Interop.SpeechRequested += Plugin.Windows10.VoiceSpeech.StartListening;
Windows10Interop.StopSpeechRequested += Plugin.Windows10.VoiceSpeech.StopListening;

を追加します。

f:id:Takyu:20160702153617p:plain

2-2-7. VCD.xmlを追加

下記のようにAdd New ItemでXML Fileを指定し、ファイル名をVCD.xmlとします。

f:id:Takyu:20160702154226p:plain

空のVCD.xmlに下記をコピペします。


gistc91aa6d3c3d83a23e9a36aaa915cf816

2-2-8. App.xaml.csの修正

ここが一番多いです。

まず、先頭に以下の宣言を追加します。

using Windows.Media.SpeechRecognition;
using System.Diagnostics;

次に、OnActivated()の指定箇所に、このようなコードを追記します。


gist88cdd5c5aeeabd50d5f06bebb27c7abd

f:id:Takyu:20160702154650p:plain

次に、OnLaunched()の指定箇所に、このようなコードを追記します。


gista2670e42df7bed99ef7069a91f2bf566

f:id:Takyu:20160702155016p:plain

OnLaunchedには、asyncをつけます。

2-3. Deploy

Windows10 MobileかHoloLensを接続します。

Windows 10 Mobileの場合、ARM、Deviceに指定してから、Deviceをクリックするか、Build/Deploy Solutionを選択するとアプリを実機転送できます。

f:id:Takyu:20160702155503p:plain

HoloLensの場合、上記をx86に指定すればあとは同一です。

2-4. 動作確認

アプリを起動したら、何も操作はしなくてよいので、2-1で決めた言葉をしゃべってみてください。そうすると、2-1で決めた回答文をCortanaがしゃべってくれます。

参考までに、Windows 10 MobileとHoloLensで調べた結果です。

2-4-1. Windows 10 Mobile

端末の言語設定と地域をen-USにして、上記のサンプルを実行しました。会話文をわざと下記のように書きました。

f:id:Takyu:20160702160920p:plain

結果

・Hello / Good Dayは問題なし

・Konnitihaとしゃべると、「コニッチワ」のような音声が返ってきました。


時間なくて再検証できてませんが、検証中に質問と回答を

「あなたの名前は?」/「私の名前はCortanaです」のように、ひらがな、漢字、英語が混じった書き方にしても認識できたことがありました。

Windows 10 Mobileの方は、言語設定で音声を男女で選べるようになっており、Ayumi Mobileという日本語女性の言語パックを使っているからと推測されます。

2-4-2. HoloLens

2-4-1と同じ会話文にしたところ、同じ結果になりました。

漢字やひらがなは試せてませんが、こちらは日本語の言語パックが見当たらないのでおそらく難しいと思います。


3.Tips

3-1. Switch PlatformでWindows Storeにすると、No Module Foundとなる。

下記の記事の2-1に対処方法を記載しましたのでご確認ください。

magicbullet.hatenablog.jp

3-2. サンプルプロジェクトで、UnityからBotWorldフォルダを指定したら、UnityのProject Viewで何も表示されない

f:id:Takyu:20160702144812j:plain

Assetsと同じフォルダにあるLibraryフォルダを削除してから再度開くと、無事開けました。

4. 終わりに

4-1. やや不安定??

サンプルを動かすだけのつもりだったのですが、詰まるところが多くて整理に時間がかかりました。

原因は、ソースコードの解読もそうですが、なぜか勝手にWindows Storeモジュールが消えてしまって3-1の状態になったり、Unityでただ開いただけで3-2の状態になることがあったためです。

おそらく、他の環境でも同じようになる可能性があるので、今回改良したプロジェクト一式をGithubに後日公開しようと思います。これをベースにすれば、とりあえずビルドするだけでCortanaの確認ができます。

2016/7/5 追記

zip圧縮した一式「CortanaUnityConnection.zip」をOneDriveに置きました。

https://1drv.ms/f/s!Aoq6rsyH7lzvgokf1DLsi-zNq9sgHA

当初GitHubに置くつもりでしたが、

CortanaUnityConnection\EXPORT\Players

の中身が2GB近くになってしまったためzip圧縮を置く方法に切り替えました。(ここを削除すると、Visual StudioでDeployができなくなる)

もし削除できるならば、後日小さくしたものも公開します。

4-2. 次の予定

なお、今回の方法では、UnityからCortanaに対して働きかける処理がメインでした。

色々調べた結果、Cortanaで音声を認識したらUnityに知らせる機能を作ることができたので、次回はその方法を紹介しようと思います。