MRが楽しい

MRやVRについて学習したことを書き残す

公式チュートリアル「MR and Azure 303 6章」を試してみる

本日はチュートリアルの実施枠です。
Academyの「MR and Azure 303: Natural language understanding (LUIS)」の実施内容をまとめます。
docs.microsoft.com
前回記事の続きです。
bluebirdofoz.hatenablog.com
今回は「Chapter 6」です。

Chapter 6:Create the LUISManager class

2番目に作成するスクリプトは LuisManager クラスです。
このクラスは以下を担当します。
・MicrophoneManager クラスから口述テキストを受け取り、分析を行う Azure Language Understanding APIに送信します。
JSON レスポンスをデシリアライズし、Behaviors クラスの適切なメソッドを呼び出してアクションをトリガーします。

1.Script フォルダを開きます。
2.フォルダ内で右クリックして、Creapte -> C# Script を選択します。
Script の名称は LuisManager に設定します。
f:id:bluebirdofoz:20180909221157j:plain

3.新しいスクリプトをダブルクリックしてVisual Studioで開きます。
4-11.以下の通り、スクリプトを編集します。
・LuisManager.cs

// 名前空間の追加
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.Networking;

public class LuisManager : MonoBehaviour {
    //this class represents the LUIS response
    // このクラスはLUIS応答を表します
    [System.Serializable]
    public class AnalysedQuery
    {
        public TopScoringIntentData topScoringIntent;
        public EntityData[] entities;
        public string query;
    }

    // This class contains the Intent LUIS determines 
    // to be the most likely
    // このクラスには近似性が高いと判断されたインテントLUISが含まれています
    [System.Serializable]
    public class TopScoringIntentData
    {
        public string intent;
        public float score;
    }

    // This class contains data for an Entity
    // このクラスには、エンティティが入ります
    [System.Serializable]
    public class EntityData
    {
        public string entity;
        public string type;
        public int startIndex;
        public int endIndex;
        public float score;
    }

    // help to access instance of this object
    // このオブジェクトのインスタンスにアクセスするのに利用します
    public static LuisManager instance;

    //Substitute the value of luis Endpoint with your own End Point
    // luis Endpoint 変数の値は自身のエンドポイントURLに置き換えます
    string luisEndpoint = "https://westus.api.cognitive... add your endpoint from the Luis Portal";

    /// <summary>
    /// Initialises this class
    /// 初期化クラス
    /// </summary>
    private void Awake()
    {
        // allows this class instance to behave like a singleton
        // このクラスをシングルトンと同じように動作させます
        instance = this;
    }

    /// <summary>
    /// Call LUIS to submit a dictation result.
    /// ディクテーション結果を提出するため、LUISを呼び出します。
    /// 更にレスポンスを受け取り、デシリアライズします。
    /// </summary>
    public IEnumerator SubmitRequestToLuis(string dictationResult)
    {
        WWWForm webForm = new WWWForm();

        string queryString;

        queryString = string.Concat(Uri.EscapeDataString(dictationResult));

        using (UnityWebRequest unityWebRequest = UnityWebRequest.Get(luisEndpoint + queryString))
        {
            unityWebRequest.downloadHandler = new DownloadHandlerBuffer();

            yield return unityWebRequest.SendWebRequest();

            long responseCode = unityWebRequest.responseCode;

            try
            {
                using (Stream stream = GenerateStreamFromString(unityWebRequest.downloadHandler.text))
                {
                    StreamReader reader = new StreamReader(stream);

                    AnalysedQuery analysedQuery = new AnalysedQuery();

                    analysedQuery = JsonUtility.FromJson<AnalysedQuery>(unityWebRequest.downloadHandler.text);

                    //analyse the elements of the response 
                    // 応答の要素を分析します
                    AnalyseResponseElements(analysedQuery);
                }
            }
            catch (Exception exception)
            {
                Debug.Log("Luis Request Exception Message: " + exception.Message);
            }

            yield return null;
        }
    }

    public static Stream GenerateStreamFromString(string receivedString)
    {
        MemoryStream stream = new MemoryStream();
        StreamWriter writer = new StreamWriter(stream);
        writer.Write(receivedString);
        writer.Flush();
        stream.Position = 0;
        return stream;
    }

    /// <summary>
    /// 結果のAnalysedQueryを読み込んでエンティティを決定します
    /// これらのエンティティが決定されると、そのエンティティが
    /// Behaviors クラスのインスタンスに渡され、アクションで使用されます。
    /// </summary>
    private void AnalyseResponseElements(AnalysedQuery aQuery)
    {
        string topIntent = aQuery.topScoringIntent.intent;

        // Create a dictionary of entities associated with their type
        // 型に関連付けられたエンティティの Dictionary インスタンスを作成します
        Dictionary<string, string> entityDic = new Dictionary<string, string>();

        foreach (EntityData ed in aQuery.entities)
        {
            entityDic.Add(ed.type, ed.entity);
        }

        // Depending on the topmost recognised intent, read the entities name
        // エンティティ名を読み取ります
        // 一番スコアが高く認識されたインテントに依存します。
        switch (aQuery.topScoringIntent.intent)
        {
            case "ChangeObjectColor":
                string targetForColor = null;
                string color = null;

                foreach (var pair in entityDic)
                {
                    if (pair.Key == "target")
                    {
                        targetForColor = pair.Value;
                    }
                    else if (pair.Key == "color")
                    {
                        color = pair.Value;
                    }
                }

                Behaviours.instance.ChangeTargetColor(targetForColor, color);
                break;

            case "ChangeObjectSize":
                string targetForSize = null;
                foreach (var pair in entityDic)
                {
                    if (pair.Key == "target")
                    {
                        targetForSize = pair.Value;
                    }
                }

                if (entityDic.ContainsKey("upsize") == true)
                {
                    Behaviours.instance.UpSizeTarget(targetForSize);
                }
                else if (entityDic.ContainsKey("downsize") == true)
                {
                    Behaviours.instance.DownSizeTarget(targetForSize);
                }
                break;
        }
    }
}

※ この時点で、Unity Editor Consoleパネルにエラーが表示されます(「The name ‘Behaviours’ does not exist...」)。
これは、コードが Behaviours クラスを参照するためです。Behaviours クラスは、次の章で作成します
f:id:bluebirdofoz:20180909221139j:plain

12.Visual Studio で変更を保存して Unity に戻ります。
f:id:bluebirdofoz:20180909221147j:plain


Chapter 6 はここまでです。
次回は Chapter 7 を実施します。
bluebirdofoz.hatenablog.com