Feel Physics Backyard

HoloLensの出張授業をする会社で、教材を開発しています

簡単なアプリを実際に動かすHoloLens初心者向け勉強会の内容(4)エアタップでスクリプト実行

f:id:weed_7777:20170117145024g:plain

いよいよC#のプログラムをカメラに割り付け、エアタップでモデルを複製して落下させるようにします。プログラムの中身も解説します。音声認識もできるようにします。

以下の記事の続きです:

www.weed.nagoya

モデルにプログラムを割り付ける

パタパタちゃんにAirTapを割り当て

以下、山地さんがフォローして下さいました。ありがとうございます!以下ほぼ全て山地さんの説明です。

Hierarchyタブの「patapata」を選択して、Inspectorタブの一番上のチェックを外します(Sceneタブに表示されていたパタパタが消えます)。

f:id:weed_7777:20170117100548p:plain

配布したHoloLensStartdashフォルダの中にあるAirTap.csのコードがあります。Hierarchyタブの「Main Camera」を選択して、Inspectorタブから「Add Component」を押して「AirTap.cs」を追加します(検索フィールドで「a」と打てば出てきます)。プレビュー画面に「Air Tap」ボタンが出現します。

f:id:weed_7777:20170117114638p:plain

AirTapコンポーネントの2行目にある「Origin Object」の項目に、Hierarchyタブの「patapata」をドラッグアンドドロップ

f:id:weed_7777:20170117134550p:plain

UnityEditor上で実行すると、画面の左上に「AirTap」と書かれたボタンが追加されるので、ボタンを押すと先ほどパタパタが表示されていた場所にパタパタが出現し、10秒後に消えるようになります。

f:id:weed_7777:20170117133049g:plain

以下、ソースコードの抜粋です。

(1) _originObject変数について

パタパタの生成の流れとして、位置、大きさ、コンポーネント等の設定を行ったゲームオブジェクト(「patapata」のことです)を元に複製して、いくつもパタパタを出現させています。_originObject変数は「patapata」を複製するときの元になっているオブジェクトが、Hierarchyタブの「patapata」だということを覚えておくための変数になっています。

(2) OnGUI関数について

画面左上のボタンの配置とボタン押下時に実行される処理を記述しています。 今回はAirTap等実機でしか確認できない処理を実機を使用せずに動作確認できるよう、 UnityEditor上で実行する場合はボタンを配置して、ボタン押下時にその処理を実行させるために使用しています。

(3) SpawnBox関数について

名前は最初にパタパタではなく、箱を作成するようにしていた時の名残りなのであまり気にしないでください、とのことです。 _originObject変数に値が設定されている場合は、そのオブジェクトを複製し、表示処理を有効化、最後に10秒で消滅するように設定しています。これにより、Hierarchyタブにある「patapata」と同様の情報(位置やコンポーネント等)を持ったオブジェクトを生成しています。

...

public class AirTap : MonoBehaviour {

    //生成する時の元になるオブジェクト (1)
    [SerializeField]private GameObject _originObject ;

...

    void Start () {

        _gestureRecognizer = new GestureRecognizer( );
        //認識するジェスチャータイプの設定.
        _gestureRecognizer.SetRecognizableGestures(GestureSettings.Tap);
        //ジェスチャー実行時に呼び出される関数の設定.
        _gestureRecognizer.TappedEvent += AirTapEvent;
        //ジェスチャーの認識を開始.
        _gestureRecognizer.StartCapturingGestures( );

    }

    void Update () {

        ...

    }

//Unityエディターで実行中の場合のみコンパイル.
#if UNITY_EDITOR
    private void OnGUI( )
    {
        //座標(10, 10)から大きさ(100, 60)、ラベル「AirTap」のボタンを作る (2)
        if( true == GUI.Button(new Rect(10, 10, 100, 60), "AirTap") ){
            SpawnBox( );
        }

        return;
    }
#endif

    ...

    void AirTapEvent (InteractionSourceKind source, int tapCount, Ray headRay)
    {
        SpawnBox( );
        return;
    }

    ...

    void SpawnBox( )
    {

    ...

        GameObject newObject ;
        //_originBoxと同じ構成のオブジェクトを生成 (3-1)
        newObject = Instantiate(_originObject);

    ...

        //10秒後にオブジェクトを削除 (3-2)
        DestroyObject(newObject, 10.0f);
        return;
    }

...

}

パタパタちゃんに重さを付ける

押すたびにパタパタが出現しますが、全て同じ場所に出続け、出現したパタパタもまだ落ちる等の物理挙動もしないので、その辺りを追加します。

Hierarchyタブの「patapata」を選択し、Inspectorタブから「Add Component」を押して、「Rigidbody」コンポーネントを追加します。

f:id:weed_7777:20170117142218p:plain

これは追加したゲームオブジェクトに物理挙動を適用させるためのコンポーネントになっています(物理でいうところの剛体です)。詳しい内容の説明は本題から外れますので、省略します。

再度UnityEditor上で実行したら、今度は「AirTap」ボタン押下でパタパタが出現し、落下していきます。

f:id:weed_7777:20170117145024g:plain

パタパタちゃんに当たり判定を付ける

ただ、連打しているとわかりますが、パタパタ同士がぶつかった際にぶつかったような挙動はせず、完全にすり抜けています。 これは当たり判定が設定されていないため発生していますので、当たり判定も追加します。「Rigidbody」の追加時と同様の流れで、今度は「SphereCollider」を追加します(これは球体の形状をした当たり判定を管理するコンポーネントになります)。

f:id:weed_7777:20170117144545p:plain

コンポーネント追加後にUnityEditor上で実行すると、今度はパタパタ同士がぶつかるようになります(結構連打しないとわかりません)。

f:id:weed_7777:20170117145024g:plain

現在の状態で実機転送すると、AirTap動作に反応してパタパタが生成されて、落ちていくものの、現実世界の障害物と衝突するという部分が実装されていないため、床をすり抜けてどこまでも落ちていってしまいます。

現実の障害物で仮想の物体が遮られるようにする

次は、空間マッピングを使って現実世界の床や壁、机などと衝突判定をとれるようにします。

Projectタブから「Assets/HoloToolkit/SpatialMapping/Prefabs」とたどっていき、そこにある「SpatialMapping」というファイルをHierarchyタブにドラッグアンドドロップします。(SpatialMappingはUnityのprefabファイルです。)

このprefabファイルが配置されていると、現実世界の障害物と衝突を行えるようになります。たったこれだけです

既にパタパタには「SphereCollider」を設定しているため、当たり判定がついているので、これだけで実機転送すれば、床や壁に衝突するのがわかると思います。

音声認識

実装

実装は以下のように行います:

  1. 配布データの「HoloLensStartdash/Assets/Script/Voice_UnityChan.cs」を自身のプロジェクトのAssets以下の任意のパスにコピーし、
  2. そのソースファイルをUnity-chanにAdd Componentする

(ソースファイル内で音声認識から音声認識による再生モーションの切り替えを行っています)。

プログラムの要点

以下は「Voice_UnityChan.cs」の要点です:

音声認識の下準備について

  1. 【下準備1】認識したい単語(or文章)と認識した際に実行したい関数の組み合わせリストを作成
  2. 【下準備2】音声認識したい単語(or文章)のリストをコンストラクタ引数として、音声認識用のオブジェクトを生成
  3. 【下準備3】何かしらの単語(or文章)を認識した時点で呼ばれるコールバック関数を設定
  4. 【下準備4】音声認識開始

ソースコード

ソースコード上の下記4行がそれぞれ4点の処理に該当します。

_keywords.Add("Next", NextAnimation);

_keywordRecognizer = new KeywordRecognizer(_keywords.Keys.ToArray( ));
_keywordRecognizer.OnPhraseRecognized += KeywordRecognizer_OnPhraseRecognized;
_keywordRecognizer.Start( );

認識した単語(or文章)の識別方法

【下準備3】で設定したコールバック関数が呼ばれた際の処理です。何かしらの単語(or文章)を認識した際に、【下準備3】で設定したコールバック関数が呼ばれ、その関数の引数に認識した単語(or文章)の情報が入っています。

その引数の情報と、【下準備1】で作成した組み合わせリストを使って、どの単語(or文章)が認識されたかを識別し、対応した関数を呼んでいます。

その他のコードは大体Unityちゃんのモーションを切り替えるためのコードになっているため、説明は省略します。

おまけ:会場で見られたハマりどころ

Windows 8.1

ビルドはできるのですが、実機転送できません(山地さん)。Windows 10を使いましょう。

Unityを普通にインストール

MS Storeオプションを付けずにインストールすると、ビルドのときに一からダウンロードし直しになります。700MB。40分かかりました。

おわりに

実際にHoloLensアプリが動いたときは嬉しかったですし、また、このようなまとめ記事を書かさせてもらえるのも、ひとえに山地さんのおかげです。

本当にありがとうございます。

HoloLensスタートダッシュの記事一覧

www.weed.nagoya