2018/07/02

Unity+Myo(ジェスチャーを活用して牛乳を搾るゲームを作りました)

blog-post-29-content

Blogをいつもご覧いただきありがとうございます。 先日「Myo」のジェスチャーでゲームを作ってみましたので今回はここでジェスチャーの使い方を紹介しようと思います。

下記のURLはゲームの映像です。
https://www.youtube.com/watch?v=4Jz7y1n3Iec


· Myoってどんなもの?

Myoアームバンドは、腕、手首、指のジェスチャーで、
デバイスをワイヤレス操作することができます。

下記のURLはMyoの公式サイトです。
https://www.myo.com


· Myoのジェスチャーの紹介

デフォルトで認識するプリセットジェスチャーは下記のとおりです。

· グー(Fist)
· パー(FingersSpread)
· ダブルタップ(DoubleTap)
· 手首で手を左に仰ぐ動作(WaveIn)
· 手首で手を右に仰ぐ動作(WaveOut)
· リラックス(Rest)

「グー」と「パー」を合わせて、モミモミすることができそうなので、私はこの二つのジェスチャーを利用して牛乳を搾るゲームを作りました。それでは、ジェスチャーの部分に入りましょう。


· sdkの導入

環境状況:
Unity2018.1.0f2
SDKバージョン:Windows SDK 0.9.0
Firmware: 1.5.1970
https://developer.thalmic.com/downloads
SDKを持っていない人は上記のサイトからダウンロードできます。

blog-post-29-content

blog-post-29-content1

SDKをダウンロードして、Unityにインポートしましたが、エラーが三つ出ました。

エラーが発生しているスクリプト(ColorBoxByPose)をチェックしたら、
レンダリングの設定の書き方が古すぎますので、
Unity2018.1.0f2(恐らくUnity2017以降のバージョン)では、書き方を変える必要がありますね。

では、そこの書き方を変えましょう!

blog-post-29-content2

上記のように修正してエラーが消えるはずです。

次はMyoをコントロールするために、SDKが用意してくれたプリハブをシーンに入れます。

blog-post-29-content3

サンプルシーンの中で「Joint」というGameObjectがあります。このGameObjectに存在するスクリプト(JointOrientation)がMyoデバイスの方向を管理しています。これをプリハブにして、自分のシーンに適用します。

方向を制御するスクリプトできたので、次はジェスチャー検出のコードですね。

それでは、ジェスチャー検出用のスクリプトを作りましょう。

そのオブジェクトに自分が作った「gManager」を入れて、ジェスチャー検出のコードを全部このスクリプト内に記述することにします。

blog-post-29-content4

これで、SDKのプラグインの導入が完了しました。


· ジェスチャー検出

例:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Pose = Thalmic.Myo.Pose;

public class GestureManager : MonoBehaviour {
    public GameObject myo;
    ThalmicMyo thalmicMyo;

    void Start() {
        thalmicMyo = myo.GetComponent<ThalmicMyo>();
    }

    void Update() {
        Fist();
        Stroke();
    }

    // ジェスチャーは「グー」の時
    void Fist() {
        if (thalmicMyo.pose == Pose.Fist) {
            /* この部分は「グー」の処理の内容
               (牛乳を搾る機能を埋め込みました) */
        }
    }

    // ジェスチャーは「パー」の時
    void Stroke() {
        if (thalmicMyo.pose != Pose.Fist || 
            thalmicMyo.pose == Pose.FingersSpread || 
            thalmicMyo.pose == Pose.Rest) {
            /* この部分は「パー」の処理の内容
               (ここで手を離す機能と牛を撫でる機能を埋め込みました) */
        }
    }
}

「撫でる」機能は正確に言うと「パー」かリラックスの状態で手首や腕を振るという動作です。 上記のコードの通りにvoid Stroke()関数の中にMyoのジャイロの処理を埋め込めば「撫でる」ができます。

例:

void Stroke()
{
    if (thalmicMyo.pose != Pose.Fist || 
        thalmicMyo.pose == Pose.FingersSpread || 
        thalmicMyo.pose == Pose.Rest)
    {
        if (thalmicMyo.gyroscope.magnitude > 120f)
        {
            // gyroscopeのmagnitudeは120より大きい場合
            // (速く腕を振ると簡単に120を超えます。)
        }
        else if (thalmicMyo.gyroscope.magnitude < 10f)
        {
            // gyroscopeのmagnitudeは10より小さい場合
            // (腕が静止に近い場合)
        }
    }
}

ここまではもう方向変更と簡単な「グー」と「パー」の処理が実現できるようになりました。でもMyoのもう一つのスクリプト(ThalmicMyo)の内容をみていきましょう。


· ThalmicMyo

ThalmicMyoはMyoのSDKの中でコアの部分です。

下記に主要な変数名を説明します。
· ArmSynced:boolタイプの変数で、trueになったらMyoデバイスが検出できます。
·arm:左の腕と右の腕どちらかと設定できます。
·pose:Myoが検出したジェスチャを保存します。UnKnowは今のジェスチャーです。
·accelerometer:加速度の計算用のVector3タイプの変数です。約9.8 m/s^2です。
·gyroscope:今のジャイロの軸のスピードを検出できます。単位は「度/秒」
·isPaired:trueの時にMyoのデータが読み込めます。
·Vibrate:Myoが提供しているバイブレーションタイプです。三つの種類があります。

public enum VibrationType { Short, Medium, Long }

バイブレーションの書き方は下記の通りです。

例:

using VibrationType = Thalmic.Myo.VibrationType;
if(thalmicMyo.pose == Pose.Fist)
{
  thalmicMyo.Vibrate(Vibrate.Short);
}

上記の「撫でる」機能はThalmicMyoの変数を利用して実装してみました。


· 実装して気づいたこと

1.実装してみて素早いジェスチャでは認識までに若干のディレイをかんじました。デバイスの特性上仕方がない点かとおもいますが、頻繫にジェスチャーを素早くおこない操作するゲームはわりと不向きかもしれません。

2.Myo Connect(Mac/Windows上のデフォルトマネージャー)をつかってキャリブレーションを行ったほうがやはり操作感が向上します。(PC用にビルドしたアプリのみで利用可能)

3.キャリブレーションをする時にゲームをする際と同じ腕のポジションでキャリブレーションするとジェスチャの認識向上におすすめです。

4.UnityでAndoroid用のビルドをためすために、有志の方が開発したandroid+UnityのSDKのGitHubにアップされたパッケージを利用してためしました。

ただ、Myo Connectのような、マネージャーソフトがない為キャリブレーション、
個人のプロファイルの設定ができないの理由で、腕の方向やコントロール精度は満足いくものにはなりませんでした。