[備忘録]Unity で始める C#　ゲーム２個め　パズルゲーム作ってるよ！

物理エンジンを追加しよう！→**Rigidbody(剛体＝形が変わらないもの）**を使う。

**[説明]**
2D スプライトのための Rigidbody 物理挙動コンポーネント

要するに Rigidbody2D クラスは Rigidbody が 3D で提供する機能と同じものを 2D で提供します。スプライトに Rigidbody2D コンポーネントを追加することで物理エンジンによる影響を受けるようになります。つまりスプライトは重力による影響を受け、力によってスクリプトで制御できます。適切なコライダーコンポーネントを追加することでスプライトは他のスプライトとの衝突に反応するようになります。この挙動は Unity の物理挙動のシステムから全面的に導出されるものです。魅力的でリアルな物理挙動のために必要なコードはわずかであり、ゲームの中で明示的にコーディングしてないにも関わらず新鮮なゲームプレイを実現できます。

**[変数]**
**angularDrag**	回転動作の減衰値　粘り気のある液体の中を動くような表現に使える。
**angularVelocity**	角度 / 秒で示される角速度
**attachedColliderCount**	Returns the number of Collider2D attached to this Rigidbody2D.
**bodyType**	Rigidbody2D の物理的なビヘイビアのタイプ
**centerOfMass**	ローカル空間でのリジッドボディの質量の中心
**collisionDetectionMode**	他のOBとの衝突検知の方法。
**constraints**リジッドボディのモーション（移動・回転）制限。[Freeze PPosition]と[Freeze Rotation]の２種がある。Positionの「ｘ」か「ｙ」をオンにするとそのGOは縦か横かのどちらかにしか動かなくなる。rotationの「ｚ」をオンにすると、GOは移動しても回転しなくなる。
**drag**	Drag 係数
**freezeRotation**	物理演算による回転の影響を受けるかどうか
**gravityScale**	オブジェクトが重力により影響を受ける度合い 1より小さいと無重力。
**inertia**	リジッドボディの回転慣性
**interpolation**	スムージングの設定。処理の重さが原因で動きがぎこちなくなるときに利用する。
**isKinematic**	オンにすると一時的に物理エンジンの影響を無効化できる。Unityでは物理的な動きが必要ないゲームでもrigidbody2dを利用するので、そのときにオンにしてキャラの座標を書き換えて動かします。物理的な動きが無効でも、rigidbody2dは衝突判定などで役に立つ。
**Linear Drag** 移動の減衰値　粘り気のある液体の中を動くような表現に使える。
**mass	Rigidbody の重さ　質量が大きいと動かすのに大きな力がいる。
**position**	Rigidbody の位置
**rotation**	Rigidbody の回転
**sharedMaterial**	PhysicsMaterial2D は Rigidbody2D にアタッチされたすべての Collider2D に適用されています。
**simulated**	リジッドボディが物理システムによってシミュレーションするかを示します。
**sleepMode**	プロセッサー負荷を抑えるためのOBのスリープ方法。「Never Sleep（スリープ無効）」「Start Awake(起動時は起きているが、動かなければスリープにする）」「Start Asleep(初期ではスリープ、衝突によりスリープ解除される）」の３種。だいたい「Start Awake」でいい。
**useAutoMass**	オンにするとコライダーの形状から自動的に質量を検出する。
**useFullKinematicContacts**	kinematic/kinematic (キネマティック/キネマティック) と kinematic/static (キネマティック/静的) の衝突は可能か。
**velocity**	リジッドボディの線形速度
**worldCenterOfMass**	グローバル空間でのリジッドボディの質量の中心を取得します。

(引用:Unity公式よりィ！）
---

---
衝突判定用のGOを用意する。
GO[OutFrame」を作成。画像をDDして、子OBにする。それにColliderコンポーネントを追加する。追加するときは、Box,Circle,Edge,Polygonの４種から選ぶ。
Physics2d→BoxColliderの順。設定するとGOの周辺に緑色の枠が出る。これは判定領域を表す。
**コライダーを使用するには、どちらにも衝突する側される側どちらにもPhysics2Dコンポーネントが追加されている必要がある。**


**背景設定**
Canvasを作って、Imageを子に持たせる。RenderModeはworldspaceにして、order in layerをマイナスの値にする（背景を画面奥にもっていく感じ）。
１が自分に近い方、１より小さいと自分より奥ってイメージ。

**GetComponentについて復習**
GetComponentはあるスクリプトから他のスクリプトの関数や変数にアクセスするための手段。方針としては、

```
アクセスしたいスクリプトを何らかのオブジェクトにつけておく
スクリプトから「オブジェクト　→　スクリプト　→　関数/変数」の順に
アクセスしていくの2ステップです。
```
引用（https://qiita.com/pilkul/items/bceca844771874d465ef）

```:使用例
Rigidbody2D rd = ball.GetComponent<Rigidbody2D>();  
rd.isKinematic = false;
```

**なんか躓いたところ**
Unity2017～からなのだろうか、Rigidbody2dのIs Kinematicが見当たらないと思ったら、Body TypeにKinematic項目が追加されており、それを変更すると同様の効果があった。

プレハブのインスタンスで行った変更をプレハブから新たなインスタンスを作るときにも有効にしたい場合はインスタンス上のApplyボタンを押せば反映される。
逆にプレハブからもできる。先にプレハブを選択して設定し、そのあとインスタンスを選択して「Revert]をクリックする。[Revert]はインスタンスの設定をプレハブと一緒にするので同じ結果が得られる。

---
**Destroyメソッド**はUnityEngine.Objectクラス（Unityのすべてのクラスの親）のスタティックメソッドで、GOやCO、メソッドを削除する。クラス名なしに呼び出せる。削除後は**Instantiate（インスタンシエイト）メソッド**でプレハブから新しいインスタンスを作成する。
引数に指定したオリジナルのオブジェクトのクローンを返す。辺値を変数に代入するときは(GameObject)をつけて**キャストする**。

【復習】
**キャスト**
別名は**型変換**。普通は型が違う変数には代入ができない。

```
void Start(){
int x = 42.195f;  //整数(int)にfloat（実数）を代入している
}
```
**→エラーが起きる。**

だが、キャストすれば

```
void Start(){
int x = (int)42.195f;  //整数(int)にfloat（実数）を代入している
}
```
**→エラーにはならない**

---
衝突時の判定を行うには、**OnCollisionEnter2D**というメソッドを持つスクリプトを追加する。
これはGOが他の何かと衝突した時に呼び出される。

```:Unity公式より
オブジェクトのコライダーが別のコライダーに衝突したときに呼び出されます（2D 物理挙動のみ）

衝突に関する詳細な情報は呼び出し時に渡す Collision2D 引数に代入されます。

注記：衝突イベントは振る舞い（Behaviour）を衝突の状況に応じて制御できるよう無効化した MonoBehaviour に送信されます。

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    void OnCollisionEnter2D(Collision2D coll) {
        if (coll.gameObject.tag == "Enemy")
            coll.gameObject.SendMessage("ApplyDamage", 10);
        
    }
}
```

GOがもつTAG（タグ）という情報が使える。ほかのGOと区別することができる。敵キャラと味方キャラを区別するときなどに使える。

```
//ボールが何かの剛体に衝突した
	void OnCollisionEnter2D (Collision2D coll){
		if (coll.gameObject.tag == "OutArea") {
			//アウトエリアに衝突
			//ゲームマネージャーを取得
			GameObject gameManager = GameObject.Find ("GameManager");
			//リトライ
			gameManager.GetComponent<GameManager> ().PushRetryButton ();
		}
	}
```
OutAreaのいずれかと衝突したときに、GOクラスのFindメソッドを使ってGameManagerという名前のGOを探す。みつかったらそのGOのGameManagerコンポーネント（つまりGameManager.cs）を取得してPushRetryButtonメソッドを呼び出している。

```:Collision2D変数
collider	衝突してきたコライダー
contacts	コライダーとの具体的な衝突地点
gameObject	衝突してきたゲームオブジェクト
otherCollider	The other Collider2D involved in the collision with the collider.
otherRigidbody	The other Rigidbody2D involved in the collision with the rigidbody.
relativeVelocity	衝突した 2 つのオブジェクトの相対的な速度（読み取り専用）
rigidbody	衝突してきたRigidBody2D
transform	衝突してきたオブジェクトの Transform
```