LoginSignup
3
2

More than 5 years have passed since last update.

UnityからLuisにリクエストを送る | Unity, 会話システム

Last updated at Posted at 2018-05-13

コグニティブサービスの一種であるLUISを使って、Unityからリクエストを送るプログラムを作成しました。
作成したキャラクターと会話するときに使えるかと思ってメモ。

実行環境

Unity
LUIS(Language Understanding Intelligent Service)
- Microsoftが開発した認識システム
- 発言した内容のインテントやエンティティを返すことができる

各種インストール

  1. 以下のツールをPCにインストール

  2. 次にLUISのサインアップを行います

認識ワードの設定(LUIS)

LUISを使って「おはよう」と入力すると、以下のようにjsonが返ってくるものを作成します。

{
  "query": "おはよう",
  "topScoringIntent": {
    "intent": "挨拶をしたい",
    "score": 0.9781246
  },
  "intents": [
    {
      "intent": "挨拶をしたい",
      "score": 0.9781246
    },
    {
      "intent": "None",
      "score": 0.01577978
    }
  ],
  "entities": []
}

無題.png

プログラム作成

今回はInputFieldを使って文字列をLUISに送りました。

InputFieldにLuis.csをドラッグ、
InputField->On End EditのプルダウンからLuis->InputLoggerを選択

※参考: PG日誌 TECK Pjin

Luis.cs
using UnityEngine;
using System.Collections;
using UnityEngine.UI;
using UnityEngine.Networking;

public class Luis : MonoBehaviour {
    InputField inputField;
    string inputValue;
    public string mystr = "Failed get Request";
    string requestMessage = "null";

    // Use this for initialization
    void Start () {
        inputField = GetComponent<InputField>();
    }

    public void InputLogger()
    {sakus
        inputValue = inputField.text;
        Debug.Log("Input is : " + inputValue);


        StartCoroutine(GetTexture());
    }

    public IEnumerator GetTexture()
    {
        UnityWebRequest www = UnityWebRequest.Get("https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/~~&q=" + WWW.EscapeURL(inputValue));

        AsyncOperation checkAsync = www.Send();
        while (!checkAsync.isDone) ;
        //Debug.Log("Request Async is " + checkAsync.isDone);

        if (www.isError)
        {
            mystr = www.error;  //unknown error
            Debug.Log(www.error);
        }
        else
        {
            var json = www.downloadHandler.text;
            var x = JsonUtility.FromJson<JsonFunc<Queries>>(json);
            Debug.Log("Luis.cs Get data : " + json);
            Debug.Log("Received Query: " + x.query);
            Debug.Log("Received Intent: " + x.topScoringIntent.intent);
            Debug.Log("Received Score: " + x.topScoringIntent.score);


            mystr = x.topScoringIntent.intent;
        }

        inputField.text = "";
        inputField.ActivateInputField();

        yield return null;
    }
}

JsonFunc
using System;
using UnityEngine;
using System.Collections;

//Jsonに関する処理を行うクラス
[Serializable]
public class JsonFunc<T>
{
    public string query;
    public T topScoringIntent;

    public JsonFunc(string query, T topScoringIntent)
    {
        this.query = query;
        this.topScoringIntent = topScoringIntent;
        //Debug.Log("FromJson:" + this.data);
    }
}

[Serializable]
public class Queries
{
    public string intent;
    public double score;

    public Queries(string intent, double score) //ここのintentとかはluisの要素と一緒にしないとダメかも
    {
        this.intent = intent;
        this.score = score;
    }
}

実行結果

以下のようなログが出たらOK
log.png

プログラム詳細

気になったところだけメモ

Webリクエスト

UnityWebRequest.Get引数の中にそのまま日本語文字列を入れてしまうと文字化けを起こし、期待したjsonコードが返ってきません。
そこでWWW.EscapeURLを使ってURLエンコードをする必要があります。

UnityWebRequest www = UnityWebRequest.Get("https://westus.api.cognitive.microsoft.com/luis~~q=" + WWW.EscapeURL(requestMessage));

AsyncOperation checkAsync = www.Send();
while (!checkAsync.isDone) ;

デシリアライズ

作成したJsonFunc.csを使って、jsonから要素を取り出す作業を行います。
今回はLUISから返ってきたデータを処理するだけなので、シリアライズはしません。

var json = www.downloadHandler.text;
var x = JsonUtility.FromJson<JsonFunc<Queries>>(json);
Debug.Log("Luis.cs Get data : " + json);
Debug.Log("Received Query: " + x.query);
Debug.Log("Received Intent: " + x.topScoringIntent.intent);
Debug.Log("Received Score: " + x.topScoringIntent.score);
3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2