---
# System prepended metadata

title: Day 23 | 使用ManoMotion製作打地鼠遊戲Part1 - 手部偵測及地鼠設定
tags: [Unity]

---

# Day 23 | 使用ManoMotion製作打地鼠遊戲Part1 - 手部偵測及地鼠設定
###### tags: `Unity` 'ManoMotion' 'AR手遊'

在上一篇文章介紹了ManoMotion的安裝與介紹，今天我們要使用ManoMotion來製作打地鼠遊戲!
> **目錄**
> 遊戲機制介紹
> Step 1 地鼠設置
> Step 2 手掌辨識程式
> Step 3 地鼠程式

## 遊戲機制介紹
遊戲運行時，手機畫面的四個角落會隨機出現地鼠，

玩家需要用手控制槌子敲擊到地鼠，碰到地鼠的話，槌子會變化，

達到指定分數，遊戲就會結束!

<br>

使用到的素材有:


| 地鼠 | 地鼠洞| 槌子(前) | 槌子(後)|
| -------- | -------- | -------- |-------|
| ![](https://i.imgur.com/EpCYiOR.png)| ![](https://i.imgur.com/myiYaJA.png) | ![](https://i.imgur.com/65fkNkd.png)| ![](https://i.imgur.com/bknivUs.png)|


## Step 1 地鼠設置

在Unity 場景中，新增地鼠、地鼠洞物件，並將它放置在角落。
![](https://i.imgur.com/qyDTvqQ.png)


使用Canvas及Rect Transform 將物件設置在角落，就不會因為不同手機畫面造成物件跑掉嘍!
![](https://i.imgur.com/4Q9yqYl.png)

接著為地鼠新增Box Collider 2D，設置好適當的大小
![](https://i.imgur.com/NOb8WmY.png)

接下來就可以撰寫地鼠的程式碼了


## Step 2 手掌辨識程式
手部識別用到ManoMotion套件，在Start()中新增
```
ManomotionManager.OnManoMotionFrameProcessed += HandleManoMotionFrameUpdated;
```

並加入HandleManoMotionFrameUpdated():
* 註冊ManoMotion中手勢辨識、追蹤位置及警告文字
* 並將資訊即時傳給其他函式
```
void HandleManoMotionFrameUpdated()
    {
	GestureInfo gesture = ManomotionManager.Instance.Hand_infos[0].hand_info.gesture_info;
	TrackingInfo tracking = ManomotionManager.Instance.Hand_infos[0].hand_info.tracking_info;
	Warning warning = ManomotionManager.Instance.Hand_infos[0].hand_info.warning;

	MoveAndScaleSpookey(tracking, warning);
	HighlightSpookeyImage(warning);
    }
```
在Awake()中加入碰撞器
```
bc = gameObject.AddComponent<BoxCollider2D>() as BoxCollider2D;
bc.size = new Vector2(280, 220);
```
MoveAndScaleSpookey()中:
* 設定顯示手部辨識的圖片尺寸
* 圖片尺寸將隨手部在相機中的大小改變
* 並且設定碰撞器大小
```
  void MoveAndScaleSpookey(TrackingInfo trackingInfo, Warning warning)
	{
		if (warning != Warning.WARNING_HAND_NOT_FOUND)
		{
			spookyRectTransform.position = Camera.main.ViewportToScreenPoint(trackingInfo.palm_center);
			float width = Screen.width * trackingInfo.bounding_box.width;
			float height = Screen.height * trackingInfo.bounding_box.height;

			float size = Mathf.Min(width, height);

			bc.size = new Vector2(width,height);
			bc.transform.localPosition = spookyRectTransform.localPosition;
		}
	}
```
在Start()中加入:
* 設定圖片資訊
* 並讓手部偵測可以不斷被執行


```
Image spookeyImageHolder;
RectTransform spookyRectTransform;

[SerializeField]
Sprite openHandSprite;
[SerializeField]
Sprite closedHandSprite;

	void Start()
	{
		spookeyImageHolder = this.GetComponent<Image>();
		spookeyImageHolder.preserveAspect = true;
		spookyRectTransform = this.GetComponent<RectTransform>();
	}

```

HighlightSpookeyImage()中:
* 為圖片設定淡入淡出，讓圖片動畫可以更自然
```
void HighlightSpookeyImage(Warning warning)
	{
		if (warning == Warning.WARNING_HAND_NOT_FOUND)
		{
			FadeOut(spookeyImageHolder);
		}
		else
		{
			FadeIn(spookeyImageHolder);
		}
	}
```

新增FixedUpdate()及OnCollisionEnter2D()，控制槌子的碰撞及圖片變化
```
 private float StateSecond = 1;

 private void FixedUpdate()
    {
		StateSecond -= Time.fixedDeltaTime;

		if (StateSecond <= 0) {
			spookeyImageHolder.sprite = openHandSprite;
			FadeIn(spookeyImageHolder);
		}
	}
```
```
  private void OnCollisionEnter2D(Collision2D col)
    {
		spookeyImageHolder.sprite = closedHandSprite;
		FadeIn(spookeyImageHolder);

		StateSecond = 1;
	}
```

## Step 3 地鼠程式
首先先新增一個Monster()，並在Scene中將所有地鼠都綁上該程式。

因為需要同時管理所有地鼠，我們新增一個gameManager來管理地鼠行為。



在Monster()中加入Hide()
```
 private void Hide()
    {
        gameManager.HideMonster(gameObject);
    }
```
在gameManager()中加入HideManager()
```
  public void HideMonster(GameObject monster) 
    {
        monster.SetActive(false);
    }
```
有了隱藏，就需要新增顯示ShowManager()
```
  public void ShowMonster(GameObject monster) 
    {
        monster.SetActive(true);
    }
```
並且在Monster()中新增碰撞OnCollisionEnter2D()
```
  private void OnCollisionEnter2D(Collision2D collision)
    {
        Hide();
    }
```
---
如此一來，手部偵測及地鼠設定便完成嘍! 下一篇將會是遊戲管理，那麼我們明天見啦!











