"Unity"+"leap motion" [練習最後]: VRGUI Project-ジェスチャー認識


#最後のVRGUI Project
<a name="top"></a><ul>
<li><font color=>Step 1:　</font><a href="#a">**概要**</a></li>
<li><font color=>Step 2:　</font><a href="#b">**設置/説明**</a></li>
<li><font color=>Step 3:　</font><a href="#c">**Mainコード 1**</a></li>
<li><font color=>Step 4:　</font><a href="#d">**Mainコード 2**</a></li>
<li><font color=>Step 5:　</font><a href="#e">**Mainコード 3**</a></li>
<li><font color=>Step 6:　</font><a href="#f">**所感**</a></li>

</ul><hr/>

><div>
<a name="a"></a>**Step1**

**概要**

 目標のVideo：<a href="https://www.youtube.com/watch?v=jLp3W1gbhRk" target="_blank">[Click]</a>

 具現機能
1. Unity3DとLeapmotionを使って、簡単なジェスチャーを認識される。
2. 認識した後でMenuが出られる。
3. Menuのトグルの機能を使って、ボタンが押される。押したらメニュのイメージが変わる。
<div align="right">
<a href="#top">TopMenu</a>
</div>
</div>

<hr/>
<a name="b"></a>**Step2**

**設置のために**

必要なこと

- *Unity3D*
- *Leapmotionデバイス*
- *[LeapmotionCoreAsset_2_3_1(or higher version).unitypackage](https://developer.leapmotion.com/)*
- *[MotionRecognition.unitypackage](https://github.com/archandy/Sample1)*

**使用説明**

- *新しいunity3d projectを作る*

- *LeapMotionウェップから、ダウンロードLeapMotionCoreAsset_2_3_1(or higher).unitypackage*
リンクはこち：https://developer.leapmotion.com/

- *UnityからインポートLeapMotionアセット*
Assets -> Import Package -> Custom Package -> LeapMotionCoreAsset_2_3_1.unitypackage

- *githubから、ダウンロード MotionRecognition.unitypackage*
リンクはこち：https://github.com/archandy/Sample1

- *Unityから、インポートアセット*
Assets -> Import Package -> Custom Package -> MotionRecognition.unitypackage
- *Assets->PracticeSceneのフォルダーでTest_PatternRecog.unityをダブルクリックでEnjoy*


<div align="right">
<a href="#top">TopMenu</a>
</div>
<hr/>
<a name="c"></a>**Step3**

**Mainコード 1**
-ジェスチャーをする前何か認識することが必要だと思って。。

```csharp:patternTest_2.csの中で
//Trigger test (true: thumbTip got close to rest of fingers)
		bool patternTrigger = false;
		for (int i = 1; i<5 && !patternTrigger; ++i) {
			for(int j = 0; j<4 && !patternTrigger; ++j){
				Finger.FingerJoint joint = (Finger.FingerJoint)(j);
				Vector3 difference = leapHand.Fingers[i].JointPosition(joint).ToUnityScaled() - thumbTip;
				if(difference.magnitude < THUMB_TRIGGER_DISTANCE 
				   && leapHand.Confidence > MIN_CONFIDENCE){
					//Trigger is ON
					patternTrigger = true;
				}
			}
		}
```

-このコードはパーティクルができることを決めるんだ

```csharp:patternTest_2.csの中で
//Particle system On/Off
        switch (patternTrigger) {
        case(true): 
            //Start recording finger position
            AddPositionCache (indexTip);
            transform.FindChild("particle").gameObject.SetActive(true);
            break;
        case(false):
            transform.FindChild("particle").gameObject.SetActive(false);
            break;
        }
```
-以下はパーティクルが人差し指をつきまとうために。。

```csharp:pointerFollow
using UnityEngine;
using System.Collections;
using Leap;


public class mouseFollow : MonoBehaviour {

	void Start(){
		gameObject.SetActive (false);
	}

	// Update is called once per frame
	void Update () {
			transform.position = GetComponentInParent<patternTest_2> ().indexTip;

	}
}

```
![Screen Shot 2015-12-25 at 17.38.12.png](https://qiita-image-store.s3.amazonaws.com/0/99307/868a48d5-defe-3237-f676-535d4f382599.png)
![Screen Shot 2015-12-25 at 17.38.33.png](https://qiita-image-store.s3.amazonaws.com/0/99307/b8ec056f-ca61-b55a-7c4e-822be64925bf.png)
**人差し指でパーティクルができる。**

**<div align="center">[Mainコード 1: Youtube Videoで見に行く](https://youtu.be/23T37Z-WgWo)
</div>**
<div align="right">
<a href="#top">TopMenu</a>
</div>
<hr/>
<a name="d"></a>**Step4**

**Mainコード 2**
-Triggerがされた後で上から下まで人差し指を特別な条件を満足しながら動いたら、メニューが出ることができるために。

```csharp:patternTest_2.csの中で
	//Add finger position
	void AddPositionCache(Vector3 position)
	{
		positions_.Insert(0, position);
		if (positions_.Count > positionCacheNum) {
			positions_.RemoveAt(positions_.Count - 1);
		}
	}

	//Detecting finger Gesture (Up||Down)
	bool DetectFingerGesture ()
	{
		var positionSum = Vector3.zero;

		for (int i = 0; i<positions_.Count; i++) {
			positionSum += positions_ [i];
			//Distance between First and Last Point
			float disBtwFirstLast = Vector3.Distance (positions_ [i], positions_ [0]);
			//X-coordinate distance change of the finger
			float xPositionCheck = Mathf.Abs (positions_ [i].x - positions_ [0].x);
			//Y-coordinate distance change of the finger
			float yPositionCheck = (positions_ [i].y - positions_ [0].y);

			//Gesture trigger checking point
			if (disBtwFirstLast > 3.0f && xPositionCheck < 0.05f && velocity>0.8f) {

				if (yPositionCheck > 0) {
					//Downward Motion
					Debug.Log ("Down Motion PASS");
					b1.SetActive(true);
					b2.SetActive(true);
					b3.SetActive(true);
					b4.SetActive(true);
					iTween.MoveTo (b1, iTween.Hash ("path", iTweenPath.GetPath ("BtnPath1"), "time", 1.20,"easetype","easeOutBack"));
					iTween.MoveTo (b2, iTween.Hash ("path", iTweenPath.GetPath ("BtnPath2"), "time", 1.20,"easetype","easeOutBack"));
					iTween.MoveTo (b3, iTween.Hash ("path", iTweenPath.GetPath ("BtnPath3"), "time", 1.20,"easetype","easeOutBack"));
					iTween.MoveTo (b4, iTween.Hash ("path", iTweenPath.GetPath ("BtnPath4"), "time", 1.20,"easetype","easeOutBack"));

					Reset ();
				}else if (yPositionCheck < 0) {
					//Upward Motion
					Debug.Log ("Up Motion PASS");
					iTween.MoveFrom (b1, iTween.Hash ("path", iTweenPath.GetPath ("BtnPath1"), "time", .20,"easetype","linear"));
					iTween.MoveFrom (b2, iTween.Hash ("path", iTweenPath.GetPath ("BtnPath2"), "time", .20,"easetype","linear"));
					iTween.MoveFrom (b3, iTween.Hash ("path", iTweenPath.GetPath ("BtnPath3"), "time", .20,"easetype","linear"));
					iTween.MoveFrom (b4, iTween.Hash ("path", iTweenPath.GetPath ("BtnPath4"), "time", .20,"easetype","linear"));
					b1.SetActive(false);
					b2.SetActive(false);
					b3.SetActive(false);
					b4.SetActive(false);

					Reset ();
				}
				return true;

			}
		}
		return false;
	}

	//Reseting position records
	void Reset ()
	{
		positions_.Clear();
	}
```
-上のコードでif文の条件には
>
- disBtwFirstLast > 3.0f ：最小の移動距離
- xPositionCheck < 0.05f ：縦に直線距離のためにx-coordinateの変化
- velocity>.8f：最小の速度


-イメージの右のほうに指のポジションと速力がみる。
![Screen Shot 2015-12-25 at 18.18.55.png](https://qiita-image-store.s3.amazonaws.com/0/99307/c500ae24-7f50-40e7-074b-4f1c6f86b76e.png)

-ジェスチャーを認識するメッセージがコンソールで書いている
<img width="1232" alt="Screen Shot 2015-12-25 at 18.23.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/99307/cf283d56-ac0b-eaf1-4011-6f9d563cadaa.png">
<img width="1233" alt="Screen Shot 2015-12-25 at 18.23.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/99307/322bffbc-a497-54f3-ea20-9afeefe5810c.png">

**<div align="center">[Mainコード 2: Youtube Videoで見に行く](https://youtu.be/Yz0Xo5jMFow)
</div>**
<div align="right">
<a href="#top">TopMenu</a>
</div>

<hr/>
<a name="e"></a>**Step5**

**Mainコード 3**
-人差し指とボタンが会ったら、トグルの機能でボタンがつけるとか消すことができる。
![Screen Shot 2015-12-25 at 18.41.26.png](https://qiita-image-store.s3.amazonaws.com/0/99307/99345d75-bd8c-2e9d-55d1-e01ffa69280f.png)
*ButtonトグルはLeapmotionからあるButtonDemoToggle.csを使って具現した。

**<div align="center">[Mainコード 3: Youtube Videoで見に行く](https://youtu.be/5jNTH-g4kq8)
</div>**
<br/>
-メニューが出る時、iTweenPathを使って作った
　*iTweenPathについては、こちを参考：[iTweenPathについてブログ](http://qiita.com/archandy85/items/5ee0adeb1e0c233d7881)




<div align="right">
<a href="#top">TopMenu</a>
</div>

<hr/>
<a name="f"></a>**Step6**

**所感**

完璧ではないが、簡単に目標の重要な機能を作った。トグルの機能とか、leapmotionのコードを依存する機能を依存しないで作ることがしたいが、後でするプランだ。

**後で具現したいこと**
- Toggle button script
- Different Gesture Recognition(circle, triangle, rectangle)
- Apply Music Listener
- Menu-hover function


<div align="right">
<a href="#top">TopMenu</a>
</div>
</div>