クォータービューカメラ を ３人称視点カメラ に変更する

ここでは、UnityサンプルのRoll-a-ballをベースに進めていきます
![スクリーンショット 2018-01-20 22.54.15.png](https://qiita-image-store.s3.amazonaws.com/0/59911/867b72b8-7949-e0a7-620a-97f1b89133f1.png)

![image.gif](https://qiita-image-store.s3.amazonaws.com/0/59911/e6c05abf-1dce-f0b6-734a-655e8ae6e7b3.gif)


Roll-a-ballでは、プレイヤーの移動は ```PlayerController.cs```内で次のように記述されています。

```
	void FixedUpdate ()
	{
		// Set some local float variables equal to the value of our Horizontal and Vertical Inputs
		float moveHorizontal = Input.GetAxis ("Horizontal");
		float moveVertical = Input.GetAxis ("Vertical");

		// Create a Vector3 variable, and assign X and Z to feature our horizontal and vertical float variables above
		Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);

		// Add a physical force to our Player rigidbody using our 'movement' Vector3 above, 
		// multiplying it by 'speed' - our public player speed that appears in the inspector
		rb.AddForce (movement * speed);
	}

```
水平方向の入力量をX軸、垂直方向の入力量をZ軸(前後)にあてはめています。
カメラのZ方向が前方を向いたまま変わらない場合はこれで良いのですが、
例えばカメラの向きを45度傾けた場合、左右のキーを押すとプレイヤーは画面に対して斜め４５度の方向に動いてしまいます。
![スクリーンショット-2018-01-20-23.05.55.jpg](https://qiita-image-store.s3.amazonaws.com/0/59911/1ce6d01b-77a7-d8d7-5aa2-17d69ff27077.jpeg)

カメラに対して水平/垂直に動かすようにするには、下記のように追加します

```
	void FixedUpdate ()
	{
		// Set some local float variables equal to the value of our Horizontal and Vertical Inputs
		float moveHorizontal = Input.GetAxis ("Horizontal");
		float moveVertical = Input.GetAxis ("Vertical");

		// Create a Vector3 variable, and assign X and Z to feature our horizontal and vertical float variables above
		Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
		//----<<
		float defSpd = movement.magnitude; // スピードを保存
		// movement（ワールドに対して水平/垂直）を、カメラに対してして水平/垂直に変換する
		movement = Camera.main.transform.rotation * movement;
		movement.y = 0f; // カメラの向きに対して変換したことで生まれるy成分を削除
		movement = movement.normalized * defSpd; // スピードを元に戻す
		//---->>

		// Add a physical force to our Player rigidbody using our 'movement' Vector3 above, 
		// multiplying it by 'speed' - our public player speed that appears in the inspector
		rb.AddForce (movement * speed);
	}

```

これで、カメラが傾いていても画面に対して水平/垂直に動くようになります。
![スクリーンショット-2018-01-20-23.23.28.png](https://qiita-image-store.s3.amazonaws.com/0/59911/8339b3f6-5faa-0c90-662e-3a76fe96b677.png)

|before|after|
|:----------------:|:-----------------:|
| ![image.gif](https://qiita-image-store.s3.amazonaws.com/0/59911/5baad0da-112d-a92f-19c4-ecff619eb524.gif) | ![image.gif](https://qiita-image-store.s3.amazonaws.com/0/59911/095304f9-2464-4055-6232-2568bea96a77.gif) |

次に、カメラが常にプレイヤーの後ろについてくるように（上下キーを押した時はプレイヤーが上下に移動し、左右キーを押した時はプレイヤーが回転するように）します。

Roll-A-Ballでは、カメラの移動は```CameraController.cs```の中で次のように記述されています。

```
public class CameraController : MonoBehaviour {

	// store a public reference to the Player game object, so we can refer to it's Transform
	public GameObject player;

	// Store a Vector3 offset from the player (a distance to place the camera from the player at all times)
	private Vector3 offset;

	// At the start of the game..
	void Start ()
	{
		// Create an offset by subtracting the Camera's position from the player's position
		offset = transform.position - player.transform.position;
	}

	// After the standard 'Update()' loop runs, and just before each frame is rendered..
	void LateUpdate ()
	{
		// Set the position of the Camera (the game object this script is attached to)
		// to the player's position, plus the offset amount
		transform.position = player.transform.position + offset;
	}
}
```
カメラの位置はプレイヤーの位置に初期値（スタート時のカメラとの位置関係）を足しているだけなので、プレイヤーとカメラの画面上の位置関係は変化しません。
そこで、下記のように変更します。

```
public class CameraController : MonoBehaviour {

	// store a public reference to the Player game object, so we can refer to it's Transform
	public GameObject player;
	//----<<
	private Quaternion defQuat; // カメラのrotation初期値
	private float ang; // 角度変化分
	//---->>

	// Store a Vector3 offset from the player (a distance to place the camera from the player at all times)
	private Vector3 offset;

	// At the start of the game..
	void Start ()
	{
		// Create an offset by subtracting the Camera's position from the player's position
		offset = transform.position - player.transform.position;
		//----<<
		defQuat = transform.rotation;
		ang = 0f;
		//---->>
	}

	// After the standard 'Update()' loop runs, and just before each frame is rendered..
	void LateUpdate ()
	{
		// Set the position of the Camera (the game object this script is attached to)
		// to the player's position, plus the offset amount
		//! transform.position = player.transform.position + offset;
		//----<<
		float moveHorizontal = Input.GetAxis ("Horizontal"); // 水平方向入力
		ang += moveHorizontal * Time.deltaTime * 100f; // 角度変化分
		// ワールドY軸を中心とした回転分の角度*初期角度
		transform.rotation = Quaternion.AngleAxis (ang, Vector3.up) * defQuat;
		// プレイヤー位置からカメラ後方にoffset（初期位置関係）の距離だけ離れた場所
		transform.position = player.transform.position - transform.forward * offset.magnitude;
		//---->>
	}
}
```
これで、左右キー入力でカメラがプレイヤーを中心に回転するようになりました。
上記 ```PlayerController.cs``` および ```CameraController.cs``` の変更で、クオータービューカメラをサードパーソンビューカメラに変更することができました。

![image.gif](https://qiita-image-store.s3.amazonaws.com/0/59911/86b21c8d-1fad-29e8-b8db-921315163841.gif)

ファーストパーソンカメラにするにはカメラの位置をプレイヤーに近づけ、必要があればプレイヤーのモデルを非表示にします。
![スクリーンショット 2018-01-20 23.57.40.png](https://qiita-image-store.s3.amazonaws.com/0/59911/0af06c74-3ac6-3b1b-a28f-bd579e772420.png)