Ray --3D--

■バージョン情報

	5.3.7f1

■概要

RayとはUnityが用意した線分用クラス、
または線分処理全般を指します。
Rayを使用することで、ゲームオブジェクトとの詳細な交差判定や
マウス位置を使用したオブジェクトの移動などが可能となります。

●前提
	・定期的に判定する
		Rayはゲームオブジェクトとの当たり(交差)判定として使用しますが、
		Trigger、Collisionのように衝突時や衝突中に自動で呼び出される
		メソッドがあるわけではなく、Updateやコルーチンなどのメソッド内で
		専用のメソッドを呼び出す必要があります。

	・Colliderを関連付ける
		Rayの判定は当たり判定の1種なので対象となるゲームオブジェクトには
		必ずColliderが必要です。

■Rayの作成

Rayの処理を作成するにあたり最初に行うことは
「どの位置」から、「どの方向」を決めることです。
この決定はRayクラスが用意されているのでインスタンス化する際の
コンストラクタなどで行ったり、判定メソッドで指定したりします。

●コンストラクタ(3Dのみ)
	・書式
		Ray(Vecotr3 開始位置, Vector3 Rayの向きベクトル)

	・作成例
		// Rayの開始位置
		Vector3 pos = new Vector3(0.0f, 0.0f, 0.0f);
		// Rayの向きベクトル
		Vector3 vec = new Vector3(0.0f, 0.0f, 1.0f);
		// Rayの作成
		Ray ray = new Ray(pos, vec);

■向きベクトルと距離

Raycastで使用するRayのベクトルは単位ベクトル以上の大きさを持ちません。
例えば向きベクトルを(0, 100.0f, 0.0f)と設定しても
単位ベクトル(0.0f, 1.0f, 0.0f)に置き換えられます。
Raycastの判定の範囲の長短は距離の指定で行います。

■2Dと3Dの違い

Rayの2Dと3Dでは挙動に違いがあります。

●Rayを飛ばしたゲームオブジェクト自体も当たる
	3DのRaycastとではRayを出しているオブジェクトは
	Colliderを付けていても判定の対象にはなりませんが、
	2DのRaycastではRayを出しているオブジェクトも対象になります。

■RaycastHit

RaycastHitはRaycastの判定で交差していたゲームオブジェクトの情報や
交差情報などが格納されいる3D用のクラスです。

●情報内容
	RaycastHitのメンバです。
	※よく利用するメンバを紹介しています。

	・collider
		交差したゲームオブジェクトのCollider情報

	・distance
		交差したオブジェクトとの距離

	・transform
		交差したオブジェクトのtransform情報

	・rigidbody
		交差したオブジェクトのRigidbody
		※関連付けがない場合はnull

	・point
		交差したオブジェクトの位置

	transformなどは対象となるゲームオブジェクトの名前や
	座標、gameObjectが取得できるの特に利用します。

■判定メソッド

Rayによる交差判定のメソッドはPhysics2DクラスのRaycastRaycastAllがあります。
このメソッドは複数のオーバーロードが用意されているので一部のみ解説をします。

●Raycast
	RaycastはRayと複数のゲームオブジェクトで判定を行います。
	複数のゲームオブジェクトと交差している場合は
	最初に交差していると判定されたゲームオブジェクトが選択されます。

	・オーバーロードその1
		戻り値:
			Rayが交差しているか

			型:bool
				true:交差している
				false:交差していない

		引数:
			Ray ray:
				開始位置と向きが設定されているRay
		
		内容:
			・Rayとゲームオブジェクトとの交差判定を行う
			・交差していればtrue、交差していなければfalseを返す

		例:
			Vector3 pos = new Vector3(0.0f, 10.0f, 0.0f);
			Vector3 direction = new Vector3(0.0f, -1.0f, 0.0f);
			Ray ray = new Ray(pos, direction);
			RaycastHit hit_info = new RaycastHit();

			/*
				Ray:
					開始位置:
						X:0.0f
						Y:0.0f
						Z:0.0f
							
					向き:
						X:0.0f
						Y:-1.0f
						Z:0.0f
			*/
			if (Physics.Raycast(ray))
			{
				Debug.Log("何かと交差した");
			}

	・オーバーロードその2
		戻り値:
			Rayが交差しているか
						
			型:bool
				true:交差している
				false:交差していない

		引数:
			Ray ray:
				開始位置と向きが設定されているRay

			out RaycastHit hitInfo
				交差情報

			float maxDistance:
				Rayの最大距離

		内容:
			・Rayとゲームオブジェクトとの交際判定を行う
				 
				・判定には距離の指定があり、範囲外のゲームオブジェクトとは
				 判定を行わない
				・交差していればtrueが返り、hitInfoに詳細情報が格納されている
			
					out:
						C#における参照渡しを示すキーワード

		例:
			Vector3 pos = new Vector3(0.0f, 10.0f, 0.0f);
			Vector3 direction = new Vector3(0.0f, -1.0f, 0.0f);
			Ray ray = new Ray(pos, direction);
			RaycastHit hit_info = new RaycastHit();
			float max_distance = 10.0f;

			/*
				Ray:
					開始位置:
						X:0.0f
						Y:0.0f
						Z:0.0f
						
					向き:
						X:0.0f
						Y:-1.0f
						Z:0.0f

				Rayの探索最大距離
						10.0f
			*/
			if (Physics.Raycast(ray, out hit_info, max_distance))
			{
				Debug.Log(hit_info.transform.name + "と交差した");
			}

	・オーバーロードその3
		戻り値:
			Rayが交差しているかどうか
						
			型:bool
				true:交差している
				false:交差していない

		引数:
			Ray ray:
				開始位置と向きが設定されているRay

			out RaycastHit hitInfo
				交差情報

			float maxDistance:
				Rayの最大距離

			int layerMask:
				判定を行うレイヤーを指定するためのマスク

		内容:
			・Rayとゲームオブジェクトとの交差判定を行い、
			 交差していればtrueが返り、hitInfoに詳細情報が格納されている
				
			・判定には距離の指定があり、範囲外のゲームオブジェクトとは
			 判定を行わない
				
			・判定を行うゲームオブジェクトはlayerMaskに指定した
			 レイヤーのみが対象となる

				out:
					C#における参照渡しを示すキーワード

		例:
			Vector3 pos = new Vector3(0.0f, 10.0f, 0.0f);
			Vector3 direction = new Vector3(0.0f, -1.0f, 0.0f);
			Ray ray = new Ray(pos, direction);
			RaycastHit hit_info = new RaycastHit();
			float max_distance = 10.0f;
			// "Character"と"Stage"レイヤーのみ交差させる
			int layer_mask = LayerMask.GetMask(new string[] { "Character", "Stage" });
			/*
				Ray:
					開始位置:
						X:0.0f
						Y:0.0f
						Z:0.0f
							
					向き:
						X:0.0f
						Y:-1.0f
						Z:0.0f
						
				Rayの探索最大距離
					10.0f

				マスクレイヤー:
					Characterレイヤー
					Stageレイヤー
			*/
			if (Physics.Raycast(ray, out hit_info, max_distance, layer_mask))
			{
				Debug.Log(hit_info.transform.name + "と交差した");
			}

●RaycastAll
	RaycastAllはRayと交差している全てのゲームオブジェクトを取得できます。
	全てのオブジェクトの取得を行うので、通常のRaycastと比較して
	処理コストが高くなっていることに注意が必要です。
	※.layerを使用して最低限の判定にするようしたりと最適化を行います

	・オーバーロードその1
		戻り値:
			Rayと交差情報が格納されているRaycastHitの配列

		引数:
			Ray ray:
				開始位置と向きが設定されているRay

		内容:
			・Rayとゲームオブジェクトとの交差判定を行う
			・交差情報はRaycastHitの配列に格納され、戻り値として返る

		例:
			Vector3 pos = new Vector3(0.0f, 10.0f, 0.0f);
			Vector3 direction = new Vector3(0.0f, -1.0f, 0.0f);
			Ray ray = new Ray(pos, direction);
			RaycastHit[] hit_list;

			/*
				Ray:
					開始位置:
						X:0.0f
						Y:0.0f
						Z:0.0f

					向き:
						X:0.0f
						Y:-1.0f
						Z:0.0f
			*/
			hit_list = Physics.RaycastAll(ray);

			for (int i = 0; i < hit_list.Length; i++)
			{
				Debug.Log(hit_list[i].transform.name + "と交差した");
			}

	・オーバーロードその2
		戻り値:
			Rayと交差しているゲームオブジェクトの情報が格納されている
			RaycastHitの配列

		引数:
			Ray ray:
				開始位置と向きが設定されているRay

			float maxDistance:
				Rayの最大距離

		内容:
			・Rayとゲームオブジェクトとの交差判定を行う
				
			・交差情報はRaycastHitの配列に格納され、戻り値として返る

			・判定には距離の指定があり、範囲外のゲームオブジェクトとは
			 判定を行わない
				
					
		例:
			Vector3 pos = new Vector3(0.0f, 10.0f, 0.0f);
			Vector3 direction = new Vector3(0.0f, -1.0f, 0.0f);
			Ray ray = new Ray(pos, direction);
			RaycastHit[] hit_list;
			float max_distance = 10.0f;;

			/*
				Ray:
					開始位置:
						X:0.0f
						Y:0.0f
						Z:0.0f

					向き:
						X:0.0f
						Y:-1.0f
						Z:0.0f

				Rayの探索最大距離
					10.0f

			*/
			hit_list = Physics.RaycastAll(ray, max_distance);

			for (int i = 0; i < hit_list.Length; i++)
			{
				Debug.Log(hit_list[i].transform.name + "と交差した");
			}

	・オーバーロードその3
		戻り値:
			Rayと交差情報が格納されているRaycastHitの配列

		引数:
			Ray ray:
				開始位置と向きが設定されているRay

			float maxDistance:
				Rayの最大距離

			int layerMask:
				判定を行うレイヤーを指定するためのマスク

		内容:
			・Rayとゲームオブジェクトとの交差判定を行う
			・交差情報はRaycastHitの配列に格納され、戻り値として返る
			・判定には距離の指定があり、範囲外のゲームオブジェクトとは
			 判定を行わない
			・判定を行うゲームオブジェクトのLayerのマスク指定を行っており、
			 指定されたレイヤー以外は判定の対象外となる

		例:
			Vector3 pos = new Vector3(0.0f, 10.0f, 0.0f);
			Vector3 direction = new Vector3(0.0f, -1.0f, 0.0f);
			Ray ray = new Ray(pos, direction);
			RaycastHit[] hit_list;
			float max_distance = 10.0f;
			// "Character"と"Stage"レイヤーのみ交差させる
			int layer_mask = LayerMask.GetMask(new string[] { "Character", "Stage" });

			/*
				Ray:
					開始位置:
						X:0.0f
						Y:0.0f
						Z:0.0f

					向き:
						X:0.0f
						Y:-1.0f
						Z:0.0f

				Rayの探索最大距離
					10.0f

				マスクレイヤー:
					Characterレイヤー
					Stageレイヤー
			*/
			hit_list = Physics.RaycastAll(ray, max_distance, layer_mask);

			for (int i = 0; i < hit_list.Length; i++)
			{
				Debug.Log(hit_list[i].transform.name + "と交差した");
			}

■可視化

Rayの可視化はDebugクラスのDrawRayを使用することで可能です。
Colliderと同様にRayの表示を行えるようにしたほうが、
デバッグ、調整で役立ちます。

●DrawRay
	戻り値:
		なし

	引数:
		Vector3:
			Rayの開始位置

		Vector3:
			Rayの向き

		Color:
			Rayの色

		float:
			描画時間(秒)

	内容:
		引数に指定した情報をもとにしてRayを描画する

	例:
		Vector3 pos = new Vector3(0.0f, 1.0f, 0.0f);
		Vector3 dir = new Vector3(0.0f, 10.0f, 0.0f);
		Color color = Color.red;
		float draw_time = 1.0f;

		Debug.DrawRay(pos, dir, color, draw_time);

●注意点
	Debug機能なので、Gameビューでの表示はされません。
	Sceneビューでのみ確認できますので、注意して下さい。

	・Sceneビュー
		unity_0173

	・Gameビュー
		unity_0174

■LayerMaskについて

Raycastで判定を行うマスク設定を行いますが、
指定がなかったとしてもレイヤーで「IgnoreRaycast」が
指定されているゲームオブジェクトは判定の対象に入りません。

	unity_0172