Live2Dで当たり判定を複数設定する

フォーラムで当たり判定が複数設定したいという人がいたので、ちょっと調べてみました。
他にもっと良いやり方がありそうですが、1番シンプルな方法を書きます。

[Live2Dフォーラム -【質問】当たり判定の沢山あるものを作りたい]
(http://forum.live2d.com/discussion/350/%E8%B3%AA%E5%95%8F-%E5%BD%93%E3%81%9F%E3%82%8A%E5%88%A4%E5%AE%9A%E3%81%AE%E6%B2%A2%E5%B1%B1%E3%81%82%E3%82%8B%E3%82%82%E3%81%AE%E3%82%92%E4%BD%9C%E3%82%8A%E3%81%9F%E3%81%84#latest)

# 開発環境
・Live2D_SDK_Unity_2.1.00_1_jpのSampleApp1プロジェクト
・Unity5.3.0f4

# 当たり判定を複数設定するやり方
**１）まずはModeler上で当たり判定を複数作ります**
プログラム上、シンプルな四角形を当たり判定としているため四角形します。
ポリゴン単位で当たり判定をつける方法はまたそのうち書きます。
<img width="513" alt="screen001.png" src="https://qiita-image-store.s3.amazonaws.com/0/15028/50055c24-d618-4f4d-e1b3-35650c5c9524.png">
<img width="499" alt="screen002.png" src="https://qiita-image-store.s3.amazonaws.com/0/15028/8f9dee8a-4505-0037-04db-736c48d0dd2a.png">
[Live2D Manual - 当たり判定があるモデル](http://sites.cybernoids.jp/cubism2/modeler/models/collision)にある通り「D_REF」という文字列が当たり判定とされます。

**２）model.jsonの当たり判定を増やします**
hit_areasは当たり判定部分です。
tap_bodyやflick_headはタップした時に再生するモーションです。

```json:haru.model.json
"hit_areas":
[
	{"name":"head0", "id":"D_REF.HEAD0"},
    {"name":"head1", "id":"D_REF.HEAD1"},
	{"name":"body0", "id":"D_REF.BODY0"},
    {"name":"body1", "id":"D_REF.BODY1"}
],
"motions":
{
	"tap_body0":
	[
		{ "file":"motions/tapBody_00.mtn" , "sound":"sounds/tapBody_00.mp3","fade_out":0}
	],
    "tap_body1":
    [
        { "file":"motions/tapBody_01.mtn" , "sound":"sounds/tapBody_01.mp3","fade_out":0},
        { "file":"motions/tapBody_02.mtn" , "sound":"sounds/tapBody_02.mp3","fade_out":0}
    ],
    "flick_head0":
    [
        { "file":"motions/flickHead_00.mtn", "sound":"sounds/flickHead_00.mp3" ,"fade_out":0}
    ] ,
    "flick_head1":
    [
        { "file":"motions/pinchIn_00.mtn", "fade_out":0}
    ] ,
```

Live2D Viewerで当たり判定表示をするとこんな感じになります
<img width="428" alt="screen003.png" src="https://qiita-image-store.s3.amazonaws.com/0/15028/e646ae6a-af1a-b0a8-80dd-3e68de4a336b.png">


**３）定義部分のソース修正する**
tap_bodyやflick_head、HIT_AREAを増やします

```csharp:LAppDefine.csの37行目あたり
// 外部定義ファイル(json)と合わせる
public const string MOTION_GROUP_IDLE			="idle";		// アイドリング
//	public const string MOTION_GROUP_TAP_BODY		="tap_body";	// 体をタップしたとき
public const string MOTION_GROUP_TAP_BODY0      ="tap_body0";    // 上半身をタップしたとき
public const string MOTION_GROUP_TAP_BODY1      ="tap_body1";    // 下半身をタップしたとき
//	public const string MOTION_GROUP_FLICK_HEAD		="flick_head";	// 頭を撫でた時
public const string MOTION_GROUP_FLICK_HEAD0    ="flick_head0";  // 髪を撫でた時
public const string MOTION_GROUP_FLICK_HEAD1    ="flick_head1";  // 顔を撫でた時
public const string MOTION_GROUP_PINCH_IN		="pinch_in";	// 拡大した時
public const string MOTION_GROUP_PINCH_OUT		="pinch_out";	// 縮小した時
public const string MOTION_GROUP_SHAKE			="shake";		// シェイク

// 外部定義ファイル(json)と合わせる
//	public const string HIT_AREA_HEAD				="head";
public const string HIT_AREA_HEAD0               ="head0";
public const string HIT_AREA_HEAD1               ="head1";
//    public const string HIT_AREA_BODY				="body";
public const string HIT_AREA_BODY0               ="body0";
public const string HIT_AREA_BODY1               ="body1";
```

**４）当たり判定部分のソース修正する**

```csharp:LAppModel.csの508行目あたり
public void FlickEvent(float x, float y)
{
    if (LAppDefine.DEBUG_LOG) Debug.Log("flick x:" + x + " y:" + y);

//        if (HitTest(LAppDefine.HIT_AREA_HEAD, x, y))
    if (HitTest(LAppDefine.HIT_AREA_HEAD0, x, y))
    {
        if (LAppDefine.DEBUG_LOG) Debug.Log("Flick face");
        StartRandomMotion(LAppDefine.MOTION_GROUP_FLICK_HEAD0, LAppDefine.PRIORITY_NORMAL);
    }
    if (HitTest(LAppDefine.HIT_AREA_HEAD1, x, y))
    {
        if (LAppDefine.DEBUG_LOG) Debug.Log("Flick face");
        StartRandomMotion(LAppDefine.MOTION_GROUP_FLICK_HEAD1, LAppDefine.PRIORITY_NORMAL);
    }
}
```

```csharp:LAppModel.csの532行目あたり
public bool TapEvent(float x, float y)
{
    if (LAppDefine.DEBUG_LOG) Debug.Log("tapEvent view x:" + x + " y:" + y);

//        if (HitTest(LAppDefine.HIT_AREA_HEAD, x, y))
    if (HitTest(LAppDefine.HIT_AREA_HEAD0, x, y))
    {
        // 顔をタップしたら表情切り替え
        if (LAppDefine.DEBUG_LOG) Debug.Log("Tapped face");
//            SetRandomExpression();
        SetExpression("f03"); 
    }
    else if (HitTest(LAppDefine.HIT_AREA_HEAD1, x, y))
    {
        // 顔をタップしたら表情切り替え
        if (LAppDefine.DEBUG_LOG) Debug.Log("Tapped face");
//            SetRandomExpression();
        SetExpression("f04"); 
    }
    else if (HitTest(LAppDefine.HIT_AREA_BODY0, x, y))
    {
        if (LAppDefine.DEBUG_LOG) Debug.Log("Tapped body");
        StartRandomMotion(LAppDefine.MOTION_GROUP_TAP_BODY0, LAppDefine.PRIORITY_NORMAL);
    }
    else if (HitTest(LAppDefine.HIT_AREA_BODY1, x, y))
    {
        if (LAppDefine.DEBUG_LOG) Debug.Log("Tapped body");
        StartRandomMotion(LAppDefine.MOTION_GROUP_TAP_BODY1, LAppDefine.PRIORITY_NORMAL);
    }
    return true;
}
```

**５）これで複数当たり判定モードが完成です！**
![004.gif](https://qiita-image-store.s3.amazonaws.com/0/15028/d2881b6f-0e83-547d-adfc-bf07261dbab5.gif)

# おまけ
ちなみにWebGL版の場合は、修正するソースクラス名が少し違ってたりします。
(LAppModel.cs　→　LAppLive2DManager.js)

jsの場合はこちらを参考に　→　[Live2D Community - add event listeners to parts](http://community.live2d.com/discussion/272/question-add-event-listeners-to-parts#latest)