Leap Motionを使って、マウスと同じようにスクリーン上の場所を指定する操作を実装しました。以下は、開発中のVoxelorer Birdに組み込んだ作例です。
タイトルやステージ選択を横画面対応にして、Leap Motionで操作できるようになった。とりあえず展示版はこんな感じで^^ #LookingGlass #るきべん pic.twitter.com/WEGCkoNx2u
— たなかゆう (@am1tanaka) 2019年2月14日
以下のリポジトリーで公開しています。
使い方を紹介します。
目次
前提
動作確認をしたのは以下の環境です。
- Windows10
- Unity2017.4.20と2018.3.2
- Leap Motion Orion 4.0.0
- Unity Core Assets 4.4.0
WebGLについて
Unity2017.4ではビルドできませんでした。Unity2018.1にして、Unsafe Codeを許可するとビルドはできましたが、実行時にエラーが出て動きませんでした。WebGLでの動かし方は分かっていません。
環境設定
Leap MotionをUnityで使えるようにする手順はこちらの公式ページで説明されています。すでに環境を構築済みでしたら、飛ばして構いません。
- 公式ページを開きます
- DOWNLOAD ORION BETAのボタンをクリックして、Leap Motion Orionの最新版をダウンロードしてインストールします
- 公式のこちらを開きます
- DOWNLOAD UNITY CORE ASSETS X.X.Xのボタンをクリックして、Unity Core Assetsをダウンロードします
以上で下準備完了です。
デモを動かす
デモの実行方法です。
- https://github.com/am1tanaka/LeapMotionPointer を開いて、クローンするか、ZIPをダウンロードします
- Unity2017.4以降でクローンしたフォルダーを開きます
Leap Motion用のアセットがないので、以下のようなエラーが出ます。次の手順で消えますので作業を進めてください。
- 上の手順でダウンロードしたUnity Core Assetsをプロジェクトにインポートします
これでエラーが消えます。
- Projectウィンドウから、LeapMotionPointer > Demoフォルダーを開いて、Demoシーンをダブルクリックして開きます
以上でデモ用のシーンが開きます。Playするとデモが動きます。
操作方法
手を水平に開いておくのが基本姿勢です。以下のように、Leap Motionの上に手を開いて、水平にかざします。
手のひらを水平にしたまま、上下左右に手を動かして画面にカーソルが表示される場所を探してください。Leap Motionから少し奥で、30cmぐらい上の位置ぐらいで表示されると思います。
左手でも操作できます。
左右移動
手を左右に動かします。
上下移動
手を上下、あるいは前後に動かします。
上下、前後のどちらも、カーソルは上下移動と見なします。
クリック
クリックは、人差し指を下げます。
人差し指と薬指の高さの違いでクリック判定をしています。中指は見ていないので、曲げても曲げなくてもどちらでも楽な方で。
手のひらが人差し指側に傾いていると誤クリックが発生しやすくなり、操作が安定しません。
小指側に傾けておく方が安定した操作ができます。
丸いのをドラッグしたり、左上のボタンをクリックしたりしてみてください。
手のひらを小指側に傾けておけば、適当に操作してもそれっぽく動きます。
手の認識がうまくいっていないと動作が不安定になります(結構頻繁に起きます)。反対側に動いたり、クリックがおかしかったり、震えたりする場合は、手をLeap Motionの視野から一旦外してから、手を認識しなおしてください。
プロジェクトに組み込む
組み込みたいプロジェクトをUnity2017.4以降で開いてから、以下の作業をします。
必要なアセットをインポート
- ダウンロードしてあるUnity Core Assets(
Leap_Motion_Core_Assets_ x.x.x.unitypackage
)をインポートします - LeapMotionPointerリポジトリーのReleasesを開いて、最新版の
LeapMotionPointerX.X.X.unitypackage
をダウンロードして、プロジェクトにインポートします - LeapMotionを使いたいシーンを開きます
- Projectウィンドウで、LeapMotionPointer > Prefabsフォルダーを開きます
- LeapMotionPointerプレハブをドラッグして、Hierarchyウィンドウにドロップします
これで準備完了です。ついでに、動作確認のためにデモ用のCanvasを配置しておくと楽です。
- ProjectウィンドウのLeapMotionPointer > Demo > Prefabsフォルダーを開いて、DemoCanvasプレハブをHierarchyウィンドウにドロップします
- EventSystemがシーンにない場合は、HierarchyウィンドウのCreateボタンをクリックして、UI > Event Systemを選択して追加します
これでLeapMotionを使ってカーソルを操作できます。カーソルは、DemoCanavsの子供のCursorオブジェクトです。これの画像を差し替えればオリジナルのものに差し替えることができます。
スクリプトで情報を得る
情報は、LeapMotionManagerEx
クラスのstatic
プロパティーで得られます。
利用したいスクリプトの冒頭に、以下のusing
を追加します。
// : using AM1.LeapMotionPointer;
bool LeapMotionManagerEx.isEnable
Leap Motionで手を確認している時にtrue
になります。
Vector3 LeapMotionManagerEx.screenPoint
Leap Motionが指している画面座標を返します。
例
// :
Debug.Log(LeapMotionManagerEx.screenPoint);
補足
デフォルトの設定では、Camera.main
のスクリーン座標を返します。Main Cameraタグが未設定だった場合など、Camera.main
が取得できない状態の時はscreenPoint
は無効な値を返します。
カメラを指定するには、シーンに配置したLeapMotionPointerオブジェクトのTarget Cameraプロパティーに目的のカメラを設定します。
Vector3 LeapMotionManagerEx.viewportPosition
Leap Motionが指している場所をビューポート座標で返します。
bool LeapMotionManagerEx.isPressDown
クリックを開始した時にtrue
になります。
例
// : if (LeapMotionManagerEx.isPressDown) { Debug.Log("クリック!"); }
bool LeapMotionManagerEx.isPress
クリック状態の時、ずっとtrue
になります。ドラッグを判定したい場合などに利用します。
例
// : if (LeapMotionManagerEx.isPress) { Debug.Log("押し続けている"); }
bool LeapMotionManagerEx.isPressUp
クリックが解除された時にtrue
になります。
例
// : if (LeapMotionManagerEx.isPressUp) { Debug.Log("クリック終了"); }
UIのボタン
UIのボタンは、クリック時に自動的に押すようにしてあります。何もしなくても反応します。
パラメーター
LeapMotionPointerの調整用パラメーターは以下の通りです。
- Leap Provider
- Leap Motionを制御しているインスタンスです。自動的に設定されるので、設定不要です
- Model Pool
- 手のモデルを表示したい時に利用します。本プロジェクトでは設定不要です
- Target Camera
LeapMotionManagerEx.screenPoint
を計算する時に使うカメラを指定します。未設定の時は、Camera.main
の値を使います。Camera.main
がnull
の時は、LeapMotionManagerEx.screenPoint
の値が設定されません
- Move Rate
- 手の動きと、カーソルの動きを対応させる係数です。この値を大きくすると、手の動きに対して、カーソルの動きが速くなります
- Visible Under
- 手の低さの下限値です。この値を小さくすると、低い位置で手を認識するようになります。小さくしすぎると指の動きが認識できなくなるので、
0.15
程度が下限です
- 手の低さの下限値です。この値を小さくすると、低い位置で手を認識するようになります。小さくしすぎると指の動きが認識できなくなるので、
- Click Threshold
- クリックを判別する人差し指と薬指の高さの差です。この値を大きくすると、クリックの誤動作は減りますが、クリックの反応が鈍くなります
- Bank Limit
- 手首の傾きがこの値よりも大きくなったら、誤動作を避けるためにクリック判定を無視します。
0
は傾き無し。0.5
が90度です
- 手首の傾きがこの値よりも大きくなったら、誤動作を避けるためにクリック判定を無視します。
- Viewport Click Limit
- 画面端でクリックを無視する範囲です。特に不要な場合は
0
のままで構いません
- 画面端でクリックを無視する範囲です。特に不要な場合は
- Flat Rate
- 手の震えを止めるための平均係数です。この値を小さくすると反応はよくなりますが、Leap Motionの誤差による震えが出やすくなります
特に調整する必要はないと思います。手を認識する場所を下げたい時に、Visible Underを設定するぐらいだと思います。
今後について
現在、UIのボタンは無理やりButton
コンポーネントを取得して、クリック時のイベントを実行するようにしています。レイヤーの指定などができず、他の要素のクリックもできないので、将来的にはEvent Systemに対応させることを考えています。
人差し指と薬指の高さ判定に手首の回転を考慮していませんが、試しに実装したら動作が不安定になったので削除した経緯があります。よい方法があればご教示いただければ幸いです。
プルリク歓迎です。