当たり判定

■概要

Unityのオブジェクト同士の当たり判定は複数用意されており、
よく利用されるのが、「重なり」と「衝突」の二つです。
前者は「Trigger」、後者は「Collision」として判定する関数が分かれています。

■事前知識

当たり判定を行う上で必要な知識として「Collider」と「Rigidbody」の
説明を先に行いたいと思います。

●Collider
	Colliderはオブジェクトの当たり範囲の設定を行うためのコンポーネントです。

	・Colliderを関連付ける方法
		Colliderは「Cube」や「Sphere」などの3Dオブジェクトには
		最初からColliderが関連付けがされています。
		オリジナルの3Dモデルには自分で割り当てる必要があり、
		ステージなどの正確な判定がいるモノはMeshColliderを、
		キャラクターなどの大雑把な判定でも問題ないモデルには
		「CapsuleCollider」や「SphereCollider」などを割り当てます。

	・Colliderの種類
		Colliderには複数の種類があります。
		以下はCollideの一例です。

		BoxCollider:
			立方体の範囲で当たりを検知する
			unity_0032

		SphereCollider:
			球体の範囲で当たりを検知する
			unity_0033

		CapsuleCollider:
			カプセル状の形で当たりを検知する
			unity_0034

		MeshCollider:
			3Dのメッシュに対して当たりを検知する
			unity_0035

	・Colliderのパラメータ
		各Colliderには専用のパラメータ設定があり、
		設定を変更することで、当たり範囲の変更が可能です。

		BoxColliderのパラメータの例:
			unity_0036

			IsTrigger:
				Colliderには共通して「IsTrigger」というチェックボックスがあり、
				このチェックボックスにチェックを入れるかどうかで
				Collider同士の当たり判定が「重なり」か「衝突」に分かれます。

			Material:
				物理属性を含んだ「PhysicMaterial」の設定を行います。

			Center:
				このColliderとオブジェクトの中心位置からの
				オフセット値を設定します。
				「0, 0, 0」はオブジェクトの中心位置となります。

				オフセット値:
					基準となる点から相対的な位置にするための数値

			Size:
				このColliderのサイズを設定できます。

●Rigidbody
	Rigidbodyはオブジェクトに衝突による物理的シミュレーションを行うために
	必要なコンポーネントです。	
	当たり判定を行うためには判定を行いたいどちらかのオブジェクトに対して、
	このRigidbodyを関連付けておく必要があります。

	・Rigidbodyを関連付ける方法
		Rigidbodyを関連付けるにはまず、関連付けたいオブジェクト決めます。
		その後、Inspectorで「Add Component」=>「Physics」=>「Rigidbody」を
		選択することでRigidbodyが関連付けられます。

	・Rigidbodyのパラメータ
		unity_0037

		Mass:
			オブジェクトの質量
			衝突などで他のオブジェクトや自分に与える演算に影響を与える

		Drag:
			オブジェクトが移動する際の空気抵抗の大きさ
			0は空気抵抗無し

		AngularDrag:
			オブジェクトが回転する際の空気抵抗の大きさ
			0は空気抵抗無し

		UseGravity:
			オブジェクトに重力抵抗を有無

		IsKinematic:
			動作をスクリプトでコントロールするかどうかを設定する
			チェックがONになっているとTransformコンポーネントの
			値変更でしか動かなくなる

		Interpolate:
			Rigidbodyによる移動がぎこちない際のオプション機能
			補間処理を適用して移動をスムーズにしてくれる

		CollisionDetection:
			高速で移動するオブジェクトの衝突判定を
			すり抜けることを防止するためのオプション

		Constraints:
			Rigidbodyに関する動きに関する制限をかける

			FreezePosition:
				衝突判定が行われた際に、チェックが入っている軸に対しては
				移動の影響を与えない

			FreezeRotation:
				衝突判定が行われた際に、チェックが入っている軸に対しては
				回転の影響を与えない

■オブジェクト同士の重なり判定

オブジェクト同士の重なり判定はオブジェクトが重なっているか否かだけを判定します。
オブジェクト同士が干渉することはありません。

●オブジェクト重なりの条件
	オブジェクト同士が重なっているかどうかを判定するには以下の準備が必要です。

	・両方のオブジェクトに対し、Colliderコンポーネントを関連付ける
	・判定を行うどちらかのオブジェクトに対してRigidbodyを関連付けする
	・どちらかのColliderコンポーネントのIsTriggerのチェックボックスをONにする

●重なり判定関数
	重なり判定を行う関数はオーバーライド関数として用意されており、
	その関数をスクリプト内で定義することで重なり判定を行えます。

	・OnTriggerEnter関数
		関数名:
			OnTriggerEnter
			
		戻り値:
			なし
		
		引数:
			Collider:当たったColliderオブジェクトの情報
		
		内容:
			オブジェクト同士が重なった瞬間に呼び出される

	・OnTriggerStay関数
		関数名:
			OnTriggerStay
		
		戻り値:
			なし
		
		引数:
			Collider:当たったColliderオブジェクトの情報
			
		内容:
			オブジェクト同士が重なっている間呼び出される

	・OnTriggerExit関数
		関数名:
			OnTriggerExit
		
		戻り値:
			なし
		
		引数:
			Collider:当たったColliderオブジェクトの情報
		
		内容:
			重なり合ったオブジェクト同士が離れた瞬間呼び出される

■重なり判定の確認

①.「Cube」オブジェクトを二つ作成し、名前を「Cube」「Cube2」とする

②.「Cube」と「Cube2」にRigidbodyを関連付けする

③.「Cube」のRigidbodyの「Use Gravity」のチェックをいれて
  「Cube2」のRigidbodyの「Use Gravity」のチェックを外す

④.「Cube」のPositionを「0, 2, 0」に設定する

⑤.「Cube」「Cube2」のBoxColliderの「IsTrigger」にチェックを入れる

⑥.「Cube」スクリプトを作成し、class Cubeの中に以下のコードを記述する

	// Cube
	// 重なり瞬間判定
	void OnTriggerEnter(Collider other)
	{
		Debug.Log (other.name + "Enter");
	}

	// 重なり中の判定
	void OnTriggerStay(Collider other)
	{
			Debug.Log (other.name + "Stay");
	}

	// 重なり離脱の判定
	void OnTriggerExit(Collider other)
	{
		Debug.Log (other.name + "Exit");
	}

⑦.スクリプト「Cube」をゲームオブジェクト「Cube」に関連付けする

■オブジェクト同士の衝突判定

オブジェクト同士の衝突判定はオブジェクトが移動した際に他のオブジェクトと
衝突しているかどうかの判定を行います。
この判定ではオブジェクト同士に何らかの物理的影響が発生します。
例えば球同士の移動に対し衝突判定を行えば、ビリヤードの用に移動の向きや、
速度に応じて衝突後の移動方向が変わります。

●オブジェクト衝突の条件
	オブジェクト同士が衝突してるかどうかを判定するには以下の準備が必要です。

	・オブジェクトに対し、Colliderコンポーネントを関連付ける
	・判定を行うどちらかのオブジェクトに対してRigidbodyを関連付けする
	・両方のColliderコンポーネントのIsTriggerのチェックボックスをOFFにする

●衝突判定関数
	衝突判定を行う関数はオーバーライド関数として用意されており、
	その関数をスクリプト内で定義することで衝突判定を行えます。

	・OnCollisionEnter関数
		関数名:
			OnCollisionEnter
		
		戻り値:
			なし
	
		引数:
			Collision:衝突があったオブジェクトのCollision情報
		
		内容:
			オブジェクト同士が衝突した瞬間に呼び出される

	・OnCollisionStay関数
		関数名:
			OnCollisionStay
		
		戻り値:
			なし
	
		引数:
			Collision:衝突があったオブジェクトのCollision情報
		
		内容:
			オブジェクト同士が衝突している間呼び出される
			※どちらも静止した状態では呼び出されない

	・OnCollisionExit関数
		関数名:
			OnCollisionExit
	
		戻り値:
			なし
	
		引数:
			Collision:衝突があったオブジェクトのCollision情報
	
		内容:
			オブジェクト同士の衝突が終了した(離れた)際に呼び出される

■衝突判定の確認

①.「Cube」オブジェクトを二つ作成し、名前を「Cube」「Cube2」とする

②.「Cube」と「Cube2」にRigidbodyを関連付けする

③.「Cube」のRigidbodyの「Use Gravity」のチェックをいれて
  「Cube2」のRigidbodyの「Use Gravity」のチェックを外す

④.「Cube」のPositionを「0.7, 2, 0」に設定する

⑤.「Cube」「Cube2」のBoxColliderの「IsTrigger」にチェックを外す
	
⑥.「Cube.cs」スクリプトを作成し、class Cubeの中に以下のコードを記述する

	// Cube.cs
	// 衝突の瞬間判定
	void OnCollisionEnter(Collision other)
	{
		Debug.Log (other.gameObject.name + "Enter");
	}

	// 衝突中の判定
	void OnCollisionStay(Collision other)
	{
		Debug.Log (other.gameObject.name + "Stay");
	}

	// 衝突離脱の判定
	void OnCollisionExit(Collision other)
	{
		Debug.Log (other.gameObject.name + "Exit");
	}

⑦.Cube.csを「Cube」に関連付けする