[Unity] 衝突判定における、IsTriggerとRigidbodyとIsKinematicのパターンを実験

# 目的
「[IsTrigger](https://docs.unity3d.com/ScriptReference/Collider-isTrigger.html)」「[Rigidbody](https://docs.unity3d.com/ScriptReference/Rigidbody.html)」「[IsKinematic](https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html)」の有無による挙動の変化を、細かく理解する

# したこと
## 前提
オブジェクト２つ「A (0,0,0)」「B (-3,0,0)」を用意し、**Aを動かして、停止しているBにぶつける**

## 試したパターン
【 Aの移動方法 】
・ transform.positionの増減： `transform.position -= transform.right * speed * Time.deltaTime`
・ Rigidbodyのvelocity： `GetComponent<Rigidbody>().velocity = transform.right * speed`

【 AのIsTrigger 】
オン / オフ

【 BのIsTrigger 】
オン / オフ

【 AのRigidbody 】
有り(+IsKinematic) / 有り / 無し

【 BのRigidbody 】
有り(+IsKinematic) / 有り / 無し

## スクリプト
```Aobject.cs
public class Aobject : MonoBehaviour {

	void Update () {
		const int speed = 3; 
		// 左に移動して、Bobjectに衝突させる 
        // 以下2通りの移動方法を切り替えて実験!
		transform.position -= transform.right * speed * Time.deltaTime;
		//GetComponent<Rigidbody>().velocity = transform.right * speed;
	}

	const string NAME = "A";
	const string OPPONENT = "Bobject";

	void OnCollisionEnter(Collision collision)
	{
		if(collision.gameObject.tag == OPPONENT)
		{
			Debug.Log(NAME + ": OnCollisionEnter");
		}
	}

	void OnTriggerEnter(Collider other)
	{
		if(other.gameObject.tag == OPPONENT)
		{
			Debug.Log(NAME + ": OnTriggerEnter");
		}
	}
}
```

```Bobject.cs
public class Bobject : MonoBehaviour {

	const string NAME = "B";
	const string OPPONENT = "Aobject";

	void OnCollisionEnter(Collision collision)
	{
		if(collision.gameObject.tag == OPPONENT)
		{
			Debug.Log(NAME + ": OnCollisionEnter");
		}
	}

	void OnTriggerEnter(Collider other)
	{
		if(other.gameObject.tag == OPPONENT)
		{
			Debug.Log(NAME + ": OnTriggerEnter");
		}
	}
}
```

# ☆まとめ☆

- Collisionイベントは、**Triggerがともにオフで、かつ動いている側がRigidbodyの場合に発火**する
- 非物理移動のtransform.positionによる移動で発生するCollisionでは、衝突される側がRigidbodyかつIsKinematicがオフでなければ、移動が**阻害されて止まってしまう**(震えて膠着するように見える)
- 物理移動のvelocityによる移動で発生するCollisionでは、衝突される側がRigidbodyかつIsKinematicオフでなければ、移動が**停止**する。
- Triggerイベントは、**Rigidbodyをどちらかにつければ発火**する
- Triggerイベントは、**IsTriggerをどちらかにつければ、両方とものオブジェクトで発火**する
- Triggerイベントは、**衝突された側が先に発火**する。ただし、**片方にしかTriggerがついていない場合は、ついている方から発火**する

# 実験結果
上記結論に至った、実験の詳細。

## Aを「transform.positionの増減」で移動する場合
|AのTrigger|BのTrigger|AのRigidbody|BのRigidbody|発火イベント|
|:-:|:-:|:-:|:-:|:-:|
|オン|オン|有り(+IsKinematic)|有り(+IsKinematic)|BのTrigger、AのTrigger。通過。|
|オン|オン|有り(+IsKinematic)|有り|BのTrigger、AのTrigger。通過。|
|オン|オン|有り(+IsKinematic)|無し|BのTrigger、AのTrigger。通過。|
|オン|オン|有り|有り(+IsKinematic)|BのTrigger、AのTrigger。通過。|
|オン|オン|有り|有り|BのTrigger、AのTrigger。通過。|
|オン|オン|有り|無し|BのTrigger、AのTrigger。通過。|
|オン|オン|無し|有り(+IsKinematic)|BのTrigger、AのTrigger。通過。|
|オン|オン|無し|有り|BのTrigger、AのTrigger。通過。|
|オン|オン|無し|無し|何も起きない|
|オン|オフ|有り(+IsKinematic)|有り(+IsKinematic)|AのTrigger、BのTrigger。通過。|
|オン|オフ|有り(+IsKinematic)|有り|AのTrigger、BのTrigger。通過。|
|オン|オフ|有り(+IsKinematic)|無し|AのTrigger、BのTrigger。通過。|
|オン|オフ|有り|有り(+IsKinematic)|AのTrigger、BのTrigger。通過。|
|オン|オフ|有り|有り|AのTrigger、BのTrigger。通過。|
|オン|オフ|有り|無し|AのTrigger、BのTrigger。通過。|
|オン|オフ|無し|有り(+IsKinematic)|AのTrigger、BのTrigger。通過。|
|オン|オフ|無し|有り|AのTrigger、BのTrigger。通過。|
|オン|オフ|無し|無し|何も起きない|
|オフ|オン|有り(+IsKinematic)|有り(+IsKinematic)|BのTrigger、AのTrigger。通過。|
|オフ|オン|有り(+IsKinematic)|有り|BのTrigger、AのTrigger。通過。|
|オフ|オン|有り(+IsKinematic)|無し|BのTrigger、AのTrigger。通過。|
|オフ|オン|有り|有り(+IsKinematic)|BのTrigger、AのTrigger。通過。|
|オフ|オン|有り|有り|BのTrigger、AのTrigger。通過。|
|オフ|オン|有り|無し|BのTrigger、AのTrigger。通過。|
|オフ|オン|無し|有り(+IsKinematic)|BのTrigger、AのTrigger。通過。|
|オフ|オン|無し|有り|BのTrigger、AのTrigger。通過。|
|オフ|オン|無し|無し|何も起きない|
|オフ|オフ|有り(+IsKinematic)|有り(+IsKinematic)|何も起きない|
|オフ|オフ|有り(+IsKinematic)|有り|AのCollison、BのCollision。A,Bともに左に移動していく。|
|オフ|オフ|有り(+IsKinematic)|無し|何も起きない|
|オフ|オフ|有り|有り(+IsKinematic)|AのCollison、BのCollision。A,Bはその場で震えて?膠着。|
|オフ|オフ|有り|有り|AのCollison、BのCollision。A,Bともに左に移動していく。|
|オフ|オフ|有り|無し|AのCollison、BのCollision。A,Bはその場で震えて?膠着。|
|オフ|オフ|無し|有り(+IsKinematic)|何も起きない|
|オフ|オフ|無し|有り|何も起きない|
|オフ|オフ|無し|無し|何も起きない|

## Aを「Rigidbodyのvelocity」で移動する場合
velocityによる移動は物理演算を伴うので、**AにはRigidbodyが必須**である。
また、**IsKinematicがオン(=物理演算無効状態)だと、velocityによる移動は不可になり、Aが動かなくなる**のでそのパターンは省略する。

|AのTrigger|BのTrigger|AのRigidbody|BのRigidbody|結果|
|:-:|:-:|:-:|:-:|:-:|
|オン|オン|有り|有り(+IsKinematic)|BのTrigger、AのTrigger。通過。|
|オン|オン|有り|有り|BのTrigger、AのTrigger。通過。|
|オン|オン|有り|無し|BのTrigger、AのTrigger。通過。|
|オン|オフ|有り|有り(+IsKinematic)|AのTrigger、BのTrigger。通過。|
|オン|オフ|有り|有り|AのTrigger、BのTrigger。通過。|
|オン|オフ|有り|無し|AのTrigger、BのTrigger。通過。|
|オフ|オン|有り|有り(+IsKinematic)|BのTrigger、AのTrigger。通過。|
|オフ|オン|有り|有り|BのTrigger、AのTrigger。通過。|
|オフ|オン|有り|無し|BのTrigger、AのTrigger。通過。|
|オフ|オフ|有り|有り(+IsKinematic)|AのCollision、BのCollision。その場で静止。|
|オフ|オフ|有り|有り|AのCollision、BのCollision。A,Bともに左に移動していく。|
|オフ|オフ|有り|無し|AのCollision、BのCollision。その場で静止。|

# 参考
## [公式マニュアル](https://docs.unity3d.com/ja/current/Manual/index.html)
- [Collider.isTrigger](https://docs.unity3d.com/ScriptReference/Collider-isTrigger.html)
- [Rigidbody](https://docs.unity3d.com/ScriptReference/Rigidbody.html)
- [Rigidbody.isKinematic](https://docs.unity3d.com/ScriptReference/Rigidbody-isKinematic.html)

## その他
- [Unityでキャラクターを移動させる方法](http://tama-lab.net/2017/05/unity%E3%81%A7%E3%82%AD%E3%83%A3%E3%83%A9%E3%82%AF%E3%82%BF%E3%83%BC%E3%82%92%E7%A7%BB%E5%8B%95%E3%81%95%E3%81%9B%E3%82%8B%E6%96%B9%E6%B3%95%E3%80%903d%E7%B7%A8%E3%80%91/#move_rigidbody)
- [Unityにおける衝突判定まとめ](https://qiita.com/nutti/items/1a284c4bf8c79386aca7)
- [Unity 当たり判定 RigidbodyとIsTriggerの実験](http://www.sawalemontea.com/entry/2017/09/06/220000)
- [Unityのrigidbodyについてる、kinematicについて](http://xengineer.hatenablog.com/entry/2014/10/31/Unity%E3%81%AErigidbody%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E3%82%8B%E3%80%81kinematic%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)

# おわりに
「*両方とも動いている場合*」が気になる...