2016年10月31日月曜日

【HoloLens開発】ユニティちゃんとHoloLensで戯れる - 音声認識編 -

前回はHololensにユニティちゃんを表示させただけでしたが、今回はそのユニティちゃんを音声認識で動かしたいと思います。


連載目次
Part 4: 【HoloLens開発】ユニティちゃんとHoloLensで戯れる - 音声認識編 - ←本記事
Part 7: 【HoloLens開発】ユニティちゃんとHoloLensで戯れる - シェアリング編 - (予定)

実際に音声認識でユニティちゃんを動かしているところを撮影したのが以下の動画です。


【HoloToolkit-Unity】
実際に音声認識を使う前にHoloToolkit-Unityという、UnityでHololens開発を行う際に有用なツールを導入しておこうと思います。
HoloToolkit-UnityはGitHubに公開されているのでここからプロジェクトを取得します。
取得したプロジェクトをUnityで開き、Assets > Export Packageでunitypackageファイルとしてアセット用に出力します。


続いて前回のプロジェクトを開いてHoloToolkit-Unityをアセットとしてインポートします。Assets > Import Package > Custom Package で出力したunitypackageを選択することでインポートできます。


インポートするとProjectのAssetsにHoloToolkitが追加されるとともに、HoloToolkitのツールバーが追加されます。
このツールバーを使うことにより簡単にHololens用の設定やビルドができるようになります。

【音声認識】
では今回の本題である音声認識を実装していこうと思います。
HoloLensの音声認識にはKeywordRecognizerクラスを使います。
KeywordRecognizerに英単語を登録(日本語は現状非対応)することで、その単語を端末が認識した際にイベントを走らせることができます。このイベントに処理を関連付けて音声認識を実行します。

Hololens開発のチュートリアルであるHologram 101のChapter#4を参考に音声認識を実装していきます。
ユニティちゃんにやってもらうモーションとしては、「Next」「Previous」を聞くとそれぞれ次・前のアニメーションに切り替えてもらうようにします。このモーションに関してはアセットのUnityChan > Scripts > IdleChangerを参考にします。

まずは自作スクリプト用にプロジェクトの直下にScriptsフォルダを作成します。このディレクトリ直下を右クリックし、Create > C# Scriptを選択して以下の2つのスクリプトを作成します。
  SpeechManager.cs
  SpeechCommands.cs


作成したスクリプトをダブルクリックするとVisual Studioが起動するので処理を実装します。
実際に実装した内容は下記ソースコードです。

using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Windows.Speech;
using System.Collections;

public class SpeechManager : MonoBehaviour {
    private Animator anim;                      // Animatorへの参照
    private AnimatorStateInfo currentState;     // 現在のステート状態を保存する参照
    private AnimatorStateInfo previousState;    // ひとつ前のステート状態を保存する参照

    KeywordRecognizer keywordRecognizer = null;
    //キーワード登録用辞書
    Dictionary<string, System.Action> keywords = new Dictionary<string, System.Action>();

    // 初期化
    void Start () {
        // 各参照の初期化
        anim = GetComponent<Animator>();
        currentState = anim.GetCurrentAnimatorStateInfo(0);
        previousState = currentState;

        // "Next"を辞書に登録
        keywords.Add("Next", () =>
        {
            // OnNextにブロードキャストを発行
            this.BroadcastMessage("OnNext");
        });

        // "Previous"を辞書に登録
        keywords.Add("Previous", () =>
        {
            // OnNextにブロードキャストを発行
            this.BroadcastMessage("OnPrevious");
        });

        // 辞書をKeywordRecognizerに登録.
        keywordRecognizer = new KeywordRecognizer(keywords.Keys.ToArray());

        // Register a callback for the KeywordRecognizer and start recognizing!
        keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
        keywordRecognizer.Start();
    }

    // Update is called once per frame
    void Update () {
        // "Next"フラグがtrueの時の処理
        if (anim.GetBool("Next"))
        {
            // 現在のステートをチェックし、ステート名が違っていたらブーリアンをfalseに戻す
            currentState = anim.GetCurrentAnimatorStateInfo(0);
            if (previousState.fullPathHash != currentState.fullPathHash)
            {
                anim.SetBool("Next", false);
                previousState = currentState;
            }
        }

        // "Back"フラグがtrueの時の処理
        if (anim.GetBool("Back"))
        {
            // 現在のステートをチェックし、ステート名が違っていたらブーリアンをfalseに戻す
            currentState = anim.GetCurrentAnimatorStateInfo(0);
            if (previousState.fullPathHash != currentState.fullPathHash)
            {
                anim.SetBool("Back", false);
                previousState = currentState;
            }
        }

    }

    private void KeywordRecognizer_OnPhraseRecognized(PhraseRecognizedEventArgs args)
    {
        System.Action keywordAction;
        if (keywords.TryGetValue(args.text, out keywordAction))
        {
            keywordAction.Invoke();
        }
    }
}
SpeechManagerにはKeywordRecognizerに単語を登録し、イベント処理を記述します。
OnStartではKeyRecognizerの初期化を実行します。KeywordRecognizerが、「Next」を認識するとSpeechCommands.csのOnNextメソッドを実行、「Previous」を認識するとOnPreviousメソッドを実行するようにしています。
OnUpdateではAnimatorのフラグ処理を実施します。この処理はIdleChangerの処理です。

using UnityEngine;
using System.Collections;

public class SpeechCommand : MonoBehaviour {
    private Animator anim;                      // Animatorへの参照

    // 初期化
    void Start () {
        anim = GetComponent<Animator>();
    }

    // 次のポーズに変更
    void OnNext()
    {
        // ブーリアンNextをtrueにする
        anim.SetBool("Next", true);
    }

    // 前のポーズに変更
    void OnPrevious()
    {
        // ブーリアンBackをtrueにする
        anim.SetBool("Back", true);
    }
}
SpeechCommandsにはイベント受付時の実際の処理を記述します。
OnNextではAnimatorのNext値をtrueに変更し次のモーションに遷移させています。
OnPreviousではAnimatorのBack値をtrueに変更し前のモーションに遷移させています。

続いて、Hierarchyのunitychanを選択し、作成したスクリプトをInspectorにドラッグ&ドロップで追加します。これでunitychanに作成したスクリプトが適用されます。


あとはUWPに書き出せばOKですが、前回のようにはBuild Settingsからは行わず、今後はHoloToolkitから行います。[HoloToolkit] > [Builds] > [Build for Hololens]で前回UWPを書き出した場所に上書きされます。書き出した後はVisual Studioで開くかどうか訊かれるので、Yesを押せばVisual Studioが起動します。


これで冒頭の動画のアプリができます。
動画では1回で音声認識ができていますが、発音や声の音量で認識しないことがあるので注意が必要です。

次回は空間認識を実装していきます。
140 180 HoloLens , Unity , 音声認識

記載されている会社名、および商品名等は、各社の商標または登録商標です。

0 コメント:

コメントを投稿

Related Posts Plugin for WordPress, Blogger...