駒の背後に当たるとくっつく

ほっそーです。
今回は僕が作成したオリジナルゲームの一部の機能を紹介します。
オリジナルゲームの内容はお互いが駒を弾き相手の駒を倒すというゲームです。

駒を弾いて相手の駒に衝突するとヒビが入る⇨(さらに衝突すると)駒が割れるという仕様になっていますが、
弾いた駒が相手の駒に当てると相手の駒を乗っ取り自分の駒としてしまいます。

#実装の概要
弾いた駒が相手の駒の背後にあった時のみ、相手の駒を乗っ取るという機能です。
乗っ取られた駒は操作ができなくなり、乗っ取った駒の一部となってしまいます。


![スクリーンショット 2018-06-06 2.50.45.png](https://qiita-image-store.s3.amazonaws.com/0/248631/7ad5029d-8fc6-e2df-c36f-f65151999d5d.png)

![スクリーンショット 2018-06-06 2.51.41.png](https://qiita-image-store.s3.amazonaws.com/0/248631/81e20dd8-cd49-f032-4cf0-7e6ac60598cb.png)

![スクリーンショット 2018-06-06 2.52.29.png](https://qiita-image-store.s3.amazonaws.com/0/248631/39a370cb-8d89-68b5-d3e2-e844f0da92a4.png)

この後、乗っ取った黒い駒を弾くと緑の駒もついていき黒い駒の一部となって機能します。
実装手順は
①Triggerを設置
②くっつくスクリプト作成
③くっついた後の駒を飛びやすくするスクリプトを作る
です。

では解説をしていきます。


#1.駒の背後に当たり判定をつける

まずは駒の背後に「Guard」を作ります。
ちなみに黒い駒自身はタグの"Koma0"というタグをつけています。

![スクリーンショット 2018-06-06 3.05.15.png](https://qiita-image-store.s3.amazonaws.com/0/248631/f69d8ac6-0034-fef6-727c-2bb8a105f0cc.png)

Guardの設定は以下の通りです。
Tagは今回"Guard0"にしてます。
見た目を透明にするために[MeshRender]のチェックを外して
[BoxCollider]の"IsTrigger"のチェックを入れています．


![スクリーンショット 2018-06-06 3.05.36.png](https://qiita-image-store.s3.amazonaws.com/0/248631/3aee67c7-fbba-23f6-4bef-0c413920adc8.png)


#2.もう一種類の駒にスクリプトをつける

![スクリーンショット 2018-06-06 4.17.56.png](https://qiita-image-store.s3.amazonaws.com/0/248631/6190163c-e0b0-c8aa-98fc-6b75aef02ac9.png)

次に白い駒に下のスクリプトをつけます。

```
 void OnTriggerEnter(Collider coli){						//駒がGuard0に入った時の動作
		if (coli.gameObject.tag == "Guard0") {
			stickingflag = 2;								//StickFlagを立てる
		}
	}

void OnCollisionEnter(Collision col) {  				//駒がGuard0に入った時の動作											
	if (col.gameObject.tag == "Koma0") {				//もし駒がGuard0に入った時にKoma0に衝突したら
		if (stickingflag == 2) {
			if (fixedJoint == null) {						//駒をくっつける動作↓
					gameObject.AddComponent<FixedJoint> ();
					fixedJoint = GetComponent<FixedJoint> ();
					fixedJoint.connectedBody = col.gameObject.GetComponent<Rigidbody> ();

					fixedJoint.enableCollision = true;			//駒をくっつける動作↑

					stick = col.gameObject;						//乗っ取った駒を自分の子にする↓
					col.gameObject.tag = "KomaStick";

					col.transform.parent = this.transform;
					stickingflag = 1;							//乗っ取った駒を自分の子にする↑

					Invoke ("Guardoff",0.5f);					//①あとで解説
					Debug.Log (1);								//①あとで解説
				}
			}  
			else if (flagC == 2) {
				col.gameObject.SendMessage ("Damage");
			}
		}
	}

void OnTriggerStay(Collider coli){				
	if(flagC ==2){
		if (coli.gameObject.tag == "KomaStick") {
			if (coli.GetComponent<Rigidbody> ()) {
				Rigidbody rigid = (Rigidbody)this.GetComponent<Rigidbody> ();
				GameObject.DestroyImmediate (rigid);
			}
		}
	}
}

void OnTriggerExit(Collider coli){							//駒がGuard0から出た時の動作
	if (coli.gameObject.tag == "Guard0") {
			stickingflag =1;									//StickFlagを下げる
	}
}
```

これで駒がくっつきます。
①は同じスクリプト内の"GuardOff"メソッドを0.5秒後に行うという意味です。
詳しくは次の章に作成。

#3.くっついた駒が飛びやすいようにする

駒同士はくっつきましたが、
このままだと、くっついた駒を飛ばすと吸収した駒の質量を感知して飛びにくくなってしまいます。
そこで前章の①の"GuardOff"メソッドで次のように書きます。
先ほどと同じスクリプト内に次を書きます。

"Guardoff" メソッド

```
public void Guardoff(){
		stick.SendMessage ("Nonrigid");
		Debug.Log (3);
	}
```

Nonrigidbodyは乗っ取られた駒のスクリプトに書かれたメソッドです。
"Nonrigidbody" メソッドは以下のように書かれています。

"Nonrigidbody" メソッド

```
public void Nonrigid(){
	Rigidbody rigid = (Rigidbody)this.GetComponent<Rigidbody>();
	GameObject.DestroyImmediate(fixedJoint);
	GameObject.DestroyImmediate(rigid);
	Destroy (guard.gameObject);
}
```



"Nonrigidbody" メソッドで行なっているのは
乗っ取った駒のRigidbodyを外しています。
Rigidbodyを外す前に'fixedJoint'を外しているのは
fixedJointの部品がついたままだとRigidbodyが外せないからです。

また"Guardoff" メソッドを①で0.5秒後に行なっているのは
ぶつかった瞬間の物理演算をまだつけていたいからです。

これで駒を乗っ取り飛ばすことができました。

![スクリーンショット 2018-06-06 4.54.51.png](https://qiita-image-store.s3.amazonaws.com/0/248631/a66c5946-9208-a62c-c1c7-fc77e52ed9ad.png)

![スクリーンショット 2018-06-06 4.55.03.png](https://qiita-image-store.s3.amazonaws.com/0/248631/1cb58b6e-6774-a1d2-46ec-c7b011182925.png)







＊参考にしたサイト
「UnityのJoint機能を使って敵にゲームオブジェクトが付くようにする」
https://gametukurikata.com/program/jointenemy