2.ホロレンズで表示される画面を実装する
ここでは[Main Camera]を編集したり、[Canvas]を追加したりしてホロレンズを装着してアプリを利用する際にどのように表示されるかを実装していきます。
まずはじめに[Main Camera]を編集していきます。[Hierarchy]から[Main Camera]を選択し、[Inspector]の[Transform]の歯車マーク->[Reset]をクリックします。次に、[Camera]の[Clear Flags]をSolid Colorにし、[Background]を#0000000とし黒にします。最後に[Inspector]の下の方にある[Add Componet]からAudio Sourseを追加します。
※Audio Sourceについてはこちらを参照してください。

続いてCanvasを追加していきます。今回はCanvas はメニューの表示に使います。[Hierarchy]->[Create]->[UI]->[Canvas]を選択します。

最初に[Inspector]の[Canvas]の[Render Modo]をWorld Spaceとします。これによって[Inspector]の[Rect Transform]が編集できるようになります。[Rect Transform]の値を以下のように変更します。

/>次に、[Hierarchy]の[Canvas]を右クリックして[UI]->[Panel]を選択します。さらに[Panel]を右クリックし[UI]->[Text]を選択します。これを四つ複製(ctrl+D)します。それぞれのTextを以下のように変更しましょう。
名前 | Transform | Width | Height
MicrophoneStatusLabel | X -80 | Y 90 | Z 0 | 300 | 30
AzureResponseLabel | X -80 | Y 30 | Z 0 | 300 | 30
DictationLabel | X -80 | Y -30 | Z 0 | 300 | 30
TranslationResultLabel | X -80 | Y -90 | Z 0 | 300 | 30
———————————————————————–
名前 |Text
———————————————————————–
MicrophoneStatusLabel | Microphone Status:
———————————————————————–
AzureResponseLabel | Azure Web Response:
———————————————————————–
DictationLabel | You just said:
———————————————————————–
TranslationResultLabel | Translation:
———————————————————————–
また、すべてのテキストの[Font Style]と[Font Size]を以下のように変更しましょう。

続いて、つくったすべてのテキストについて、それぞれの中にさらにTextを作っていきます。やり方は先ほど同様です。しかし、すべてのTextの[Inspector]が同じなので以下のように一つを作ってからコピーする方が良さそうです。[Paragraph]の[Alignment]と[Color]は先ほどと違うので注意しましょう。[Color]は#0032EAFFとします。

今作った部分は実装したときに音声に合わせて変わる部分となります。しかし、まだその動きを記述していないので動かないです。
最終的に以下のようになれば良いです。

この時点では何も動きませんので次以降のステップで動きをつけていきたいと思います。
3.スクリプトの作成
それでは先ほど作ったTextに動きをつけていきましょう。はじめに作るのは翻訳の結果を表示する部分です。まず[Project]->[Create]->[Folder]でフォルダーを作成し、名前をScriptsとしましょう。次に[Project]->[Create]->[C# Script]とし、名前をResultsとしたあと[Scripts]の中に入れます。

名前をResultsとしたあと、ダブルクリックします。Visual studioが開き編集画面になるので以下のコードを記述しましょう。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI
public class Results : MonoBehaviour {
public static Results instance;
[HideInInspector]
public string azureResponseCode;
[HideInInspector]
public string translationResult;
[HideInInspector]
public string dictationResult;
[HideInInspector]
public string micStatus;
public Text microphoneStatusText;
public Text azureResponseText;
public Text dictationText;
public Text translationResultText;
private void Awake()
{
// Set this class to behave similar to singleton
instance = this;
}
/// <summary
/// Stores the Azure response value in the static instance of Result class.
/// </summary
public void SetAzureResponse(string result)
{
azureResponseCode = result;
azureResponseText.text = azureResponseCode;
}
/// <summary
/// Stores the translated result from dictation in the static instance of Result class.
/// </summary
public void SetDictationResult(string result)
{
dictationResult = result;
dictationText.text = dictationResult;
}
/// <summary
/// Stores the translated result from Azure Service in the static instance of Result class.
/// </summary
public void SetTranslatedResult(string result)
{
translationResult = result;
translationResultText.text = translationResult;
}
/// <summary
/// Stores the status of the Microphone in the static instance of Result class.
/// </summary
public void SetMicrophoneStatus(string result)
{
micStatus = result;
microphoneStatusText.text = micStatus;
}
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
}
}
変更を保存したあとUnityに戻ります。
次に、ホロレンズのマイクで聞き取った音声を可視化したりAzure Translationに送ったりするための処理を行うスクリプトを記述していきます。先ほど同様C# Scriptを作り今度はMicrophoneManagerとします。これも同様に[Scripts]の中に入れます。
ダブルクリックしvisual studioに移動した後、以下のコードを記述します。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Windows.Speech;
public class MicrophoneManager : MonoBehaviour
{
// Help to access instance of this object
public static MicrophoneManager instance;
// AudioSource component, provides access to mic
private AudioSource audioSource;
// Flag indicating mic detection
private bool microphoneDetected;
// Component converting speech to text
private DictationRecognizer dictationRecognizer;
private void Awake()
{
// Set this class to behave similar to singleton
instance = this;
}
// Use this for initialization
void Start()
{
//Use Unity Microphone class to detect devices and setup AudioSource
if (Microphone.devices.Length > 0)
{
Results.instance.SetMicrophoneStatus("Initialising...");
audioSource = GetComponent<AudioSource>();
microphoneDetected = true;
}
else
{
Results.instance.SetMicrophoneStatus("No Microphone detected");
}
}
/// <summary
/// Start microphone capture. Debugging message is delivered to the Results class.
/// </summary
public void StartCapturingAudio()
{
if (microphoneDetected)
{
// Start dictation
dictationRecognizer = new DictationRecognizer();
dictationRecognizer.DictationResult += DictationRecognizer_DictationResult;
dictationRecognizer.Start();
// Update UI with mic status
Results.instance.SetMicrophoneStatus("Capturing...");
}
}
/// <summary
/// Stop microphone capture. Debugging message is delivered to the Results class.
/// </summary
public void StopCapturingAudio()
{
Results.instance.SetMicrophoneStatus("Mic sleeping");
Microphone.End(null);
dictationRecognizer.DictationResult -= DictationRecognizer_DictationResult;
dictationRecognizer.Dispose();
}
/// <summary
/// This handler is called every time the Dictation detects a pause in the speech.
/// Debugging message is delivered to the Results class.
/// </summary
private void DictationRecognizer_DictationResult(string text, ConfidenceLevel confidence)
{
// Update UI with dictation captured
Results.instance.SetDictationResult(text);
// Start the coroutine that process the dictation through Azure
StartCoroutine(Translator.instance.TranslateWithUnityNetworking(text));
}
}
続いてAzure Translationの翻訳機能を利用するためのスクリプトを書いていきましょう。先ほど同様にC# Scriptを作り名前をTranslatorとします。
ダブルクリックでVisual studioを開き以下のコードを記述しましょう。先ほど準備で入手したTranslator Text APIのkey1、key2いずれかを–Insert your authorizationKey–にいれます。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Xml.Linq;
using UnityEngine;
using UnityEngine.Networking;
public class Translator : MonoBehaviour {
public static Translator instance;
private string translationTokenEndpoint = "https://api.cognitive.microsoft.com/sts/v1.0/issueToken";
private string translationTextEndpoint = "https://api.microsofttranslator.com/v2/http.svc/Translate?";
private const string ocpApimSubscriptionKeyHeader = "Ocp-Apim-Subscription-Key";
//Substitute the value of authorizationKey with your own Key
private const string authorizationKey = "--Insert your authorizationKey--";
private string authorizationToken;
// languages set below are:
// English
// French
// Italian
// Japanese
// Korean
public enum Languages { en, fr, it, ja, ko };
public Languages from = Languages.en;
public Languages to = Languages.it;
private void Awake()
{
// Set this class to behave similar to singleton
instance = this;
}
// Use this for initialization
void Start()
{
// When the application starts, request an auth token
StartCoroutine("GetTokenCoroutine", authorizationKey);
}
/// <summary
/// Request a Token from Azure Translation Service by providing the access key.
/// Debugging result is delivered to the Results class.
/// </summary
private IEnumerator GetTokenCoroutine(string key)
{
if (string.IsNullOrEmpty(key))
{
throw new InvalidOperationException("Authorization key not set.");
}
using (UnityWebRequest unityWebRequest = UnityWebRequest.Post(translationTokenEndpoint, string.Empty))
{
unityWebRequest.SetRequestHeader("Ocp-Apim-Subscription-Key", key);
yield return unityWebRequest.SendWebRequest();
long responseCode = unityWebRequest.responseCode;
// Update the UI with the response code
Results.instance.SetAzureResponse(responseCode.ToString());
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
{
Results.instance.azureResponseText.text = unityWebRequest.error;
yield return null;
}
else
{
authorizationToken = unityWebRequest.downloadHandler.text;
}
}
// After receiving the token, begin capturing Audio with the MicrophoneManager Class
MicrophoneManager.instance.StartCapturingAudio();
}
/// <summary
/// Request a translation from Azure Translation Service by providing a string.
/// Debugging result is delivered to the Results class.
/// </summary
public IEnumerator TranslateWithUnityNetworking(string text)
{
// This query string will contain the parameters for the translation
string queryString = string.Concat("text=", Uri.EscapeDataString(text), "&from=", from, "&to=", to);
using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(translationTextEndpoint + queryString))
{
unityWebRequest.SetRequestHeader("Authorization", "Bearer " + authorizationToken);
unityWebRequest.SetRequestHeader("Accept", "application/xml");
yield return unityWebRequest.SendWebRequest();
if (unityWebRequest.isNetworkError || unityWebRequest.isHttpError)
{
Debug.Log(unityWebRequest.error);
yield return null;
}
// Parse out the response text from the returned Xml
string result = XElement.Parse(unityWebRequest.downloadHandler.text).Value;
Results.instance.SetTranslatedResult(result);
}
}
// Update is called once per frame
void Update () {
}
}
必要なスクリプトは全て揃ったのでスクリプトをMainCameraにドラッグ&ドロップします。

すると、 [MainCamera]内の[Inspector]に以下のドラッグ&ドロップした項目が増えています。

最後にTextを[Results]にドラッグ&ドロップし、

Translatorを以下のように変更すれば完成です。

4.使ってみよう
最後のステップです。今までに実装したものをホロレンズ上で実行してみたいと思います。ビルドする方法は こちら を参照してください。最初に行った設定を変えずに[Build]をすることに注意します。
Buildが無事完了したら、HoloLensを装着してアプリを試してみます。このように翻訳がされればOKです。