簡易ゲームに必要そうな機能たち


## ゲームオブジェクトの参照

まとめた
https://qiita.com/mo4_9/items/4d26f54bca28fd352708


## ゲームオブジェクトの表示/非表示

GameObject.SetActive
https://docs.unity3d.com/550/Documentation/ScriptReference/GameObject.SetActive.html

```c
gameObject.SetActive(false);
```

Renderer-enabled
https://docs.unity3d.com/jp/540/ScriptReference/Renderer-enabled.html

```c
GetComponent<Renderer>().enabled = false;
```


## シーン切り替え

SceneManager.LoadScene
https://docs.unity3d.com/jp/540/ScriptReference/SceneManagement.SceneManager.LoadScene.html

ex) 場面転換

```cs
SceneManager.LoadScene("next", LoadSceneMode.Single); // nextシーンに交換
```

ex) 隣の部屋を追加（BGMが続いているシーンなど）

```cs
SceneManager.LoadScene("next", LoadSceneMode.Additive); // nextシーンを追加
```

> 参考
[【Unity】俺はまだSceneManagerを全力で使っていない！](http://www.urablog.xyz/entry/2017/04/09/180155)


## ゲームオーバーエリア

ex) キャラがステージから落ちたかどうかを判定

OnTriggerEnter
https://docs.unity3d.com/550/Documentation/ScriptReference/Collider.OnTriggerEnter.html

判定エリア用の空のGameObjectをつくり、
Colliderをつけて`Is Trigger`にチェックを入れる。
これで`OnCollisionEnter`がとれないので、接触してきたものがすり抜けるが、
そのエリアに侵入したかどうかの判定はとることができる。
（あるエリアに入ったらイベントを発生させる様々な用途に使える）

OnTriggerExit
https://docs.unity3d.com/ja/540/ScriptReference/Collider.OnTriggerExit.html

逆に、指定のエリアから出ていったものを判定するやり方もできる。

> 参考
[チュートリアル > スペースシューター > Boundary](https://unity3d.com/jp/learn/tutorials/projects/space-shooter-tutorial/boundary?playlist=45993)


## 時間制御

Time.deltaTime
https://docs.unity3d.com/jp/540/ScriptReference/Time-deltaTime.html

あらかじめ経過時間（前のフレームと今のフレームの差分）をとれる変数が組み込まれているので、マシンスペックに応じてアニメーションが遅くなるということがない（時間は遅れずに、アニメーションを間引くことになる）

```c
float second;

void Update () {
	second += Time.deltaTime;
}
```

※経過時間依存を使わずに物理演算を行う場合は、Updateではなく[FixedUpdate](https://docs.unity3d.com/ja/540/ScriptReference/MonoBehaviour.FixedUpdate.html)を使う

> 参考
[Unityで経過時間、制限時間を表示する機能を作成する](https://gametukurikata.com/program/time)


## セーブ

PlayerPrefs
https://docs.unity3d.com/ja/540/ScriptReference/PlayerPrefs.html

String, Int, Floatの3種類で保存できる

> 参考
[UnityのPlayerPrefsでデータをセーブする](http://smartgames.hatenablog.com/entry/2015/01/19/004227)
[【Unity】ローカルデータの保存](http://techblog.kayac.com/unity_advent_calendar_2016_18)


## 複製

プレハブからクローンを作る

ex) 銃の弾丸を量産

Instantiate
https://docs.unity3d.com/jp/540/ScriptReference/Object.Instantiate.html

Rigidbody.AddForce
https://docs.unity3d.com/jp/540/ScriptReference/Rigidbody.AddForce.html

```cs:Gun.cs(大砲にアタッチ)
void Update () {
	if(Input.GetMouseButtonDown(0)){
		Fire ();
	}
}
void Fire() {
	// 大砲（親要素）の位置と回転をもった弾丸を生成し、
	GameObject bullet = Instantiate (BulletPrefab, transform.position, transform.rotation);
	Rigidbody rb = bullet.GetComponent<Rigidbody>();
	// 推力をvec3で設定し、力のタイプ（加速、衝撃、速度変化）を決める
	rb.AddForce(transform.up * 30, ForceMode.VelocityChange);
}
```


## 衝突

ex) 弾丸が壁に当たって爆発

OnCollisionEnter
https://docs.unity3d.com/ja/540/ScriptReference/Collider.OnCollisionEnter.html

SendMessage
https://docs.unity3d.com/jp/540/ScriptReference/GameObject.SendMessage.html

Destroy
https://docs.unity3d.com/jp/540/ScriptReference/Object.Destroy.html

```cs:BulletBeahaviour.cs(弾丸にアタッチ)
public GameObject ExplosionSeaPrefab;
public GameObject ExplosionGroundPrefab;

void OnCollisionEnter(Collision collision) {
	switch (collision.gameObject.tag) {
		case "sea":
			Instantiate(ExplosionSeaPrefab, transform.position, transform.rotation);
			break;
		case "ground":
			Instantiate(ExplosionGroundPrefab, transform.position, transform.rotation);
			// 衝突したgameObjectのメソッドをコール
			collision.gameObject.SendMessage("hit");
			break;
	}
	// 破壊
	Destroy(gameObject);
}
```

```cs:GroundBehaviour.cs（地面にアタッチ）
void hit() {
	GetComponent<Renderer>().material.color = Color.red;
}
```

タグを使って、衝突した相手に応じて処理を分岐させる。

青い部分に落ちた球は爆発せず、
黄色い部分に落ちた球は爆発している

1枚目の黄色のhit()メソッドをコールして色を変えている
※2枚目はhit()メソッドをもっていないがエラーはでない

![Untitled.gif](https://qiita-image-store.s3.amazonaws.com/0/136286/8c6fec6a-359c-c7ee-d30d-416cd3796ffa.gif "Untitled.gif")


## ユーザー操作

MonoBehaviour.OnMouseDown
https://docs.unity3d.com/jp/540/ScriptReference/MonoBehaviour.OnMouseDown.html
クリックされるオブジェクトにアタッチ

Input.GetButton
https://docs.unity3d.com/jp/540/ScriptReference/Input.GetButton.html
Booleanが返ってくる（ボタンを押したかどうか）

Input.GetAxis
https://docs.unity3d.com/jp/540/ScriptReference/Input.GetAxis.html
Booleanではなくfloatが返ってくる

`InputManager`を使用
値は以下の場所に指定されている

![スクリーンショット 2017-09-30 23.44.14.png](https://qiita-image-store.s3.amazonaws.com/0/136286/1d1d2d18-f6c1-f167-7588-1cd391bce07e.png "スクリーンショット 2017-09-30 23.44.14.png")


```cs
void Update () {
    transform.Rotate(new Vector3(
        Input.GetAxis("Vertical") * 60 * Time.deltaTime,
        Input.GetAxis("Horizontal") * 60 * Time.deltaTime,
        0),
        Space.World
    );
}
```



## ワイプ

MainCameraとは別のカメラをもう一つつくる

`Viewport Rect`でサイズを縮小し、
`Audio Listener`を切る

![スクリーンショット 2017-09-30 16.57.07.png](https://qiita-image-store.s3.amazonaws.com/0/136286/b08d2b42-62d9-23b4-373d-6177c826b632.png "スクリーンショット 2017-09-30 16.57.07.png")

Projectionをパースなしの`Orthographic`にすればミニマップになる


## uGUI

まとめた
https://qiita.com/mo4_9/items/3dd912a6b8a5af151a3c