[備忘録]Unity で始める C#　ゲーム２個め　箇条書き多め　

なんかしっくり来なかったプレハブの作り方よくよくみたらわかったのでここに記す。
→**Hierarchy**で作ったGOを**Project**に突っ込むだけ。わかりにくくなるから、Assetsの中に[Prefabs]っていうフォルダ作っとくとわかりやすいよ。
あと他のフォルダは[Resources]→画像やサウンド関連、[Scenes]→シーンを保管、[Scripts]→GameManagerやシーンごとのスクリプト　とかを作っとけばとりあえずおｋ。

---
ドラッグで移動する処理
OnMouseDragメソッドを追加する。

```;引用Unity公式より
OnMouseDrag はユーザーが GUIElement または Collider をマウスでクリックし、ドラッグしている間呼び出されます。

OnMouseDrag はマウスを押している間、毎フレーム呼び出されます。

この関数はレイヤーが「 Ignore Raycast 」のゲームオブジェクトでは呼び出されません。

Physics.queriesHitTriggers が true の場合に限り、この関数は Trigger であると示される Collider 上で呼び出されます。

OnMouseDrag は関数の中にシンプルな yield 文を使用して、コルーチンにすることができます。 このイベントは Collider または GUIElement にアタッチされているすべてのスクリプトに送信されます。

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour {
    public Renderer rend;
    void Start() {
        rend = GetComponent<Renderer>();
    }
    void OnMouseDrag() {
        rend.material.color -= Color.white * Time.deltaTime;
    }
}
```

ちょっと話が脱線するが、この２つを比較する必要がある。

```:1
//ボールが何かの剛体に衝突した
	void OnCollisionEnter2D (Collision2D coll){
		if (coll.gameObject.tag == "OutArea") {
			//アウトエリアに衝突
			//ゲームマネージャーを取得
			GameObject gameManager = GameObject.Find ("GameManager");
			//リトライ
			gameManager.GetComponent<GameManager> ().PushRetryButton ();
		}
	}
```

このとき疑問に思ったこと：6linesでgameManagerにGameManagerを入れた。そのあとのGetComponentで＜GameManager>を指定するのはなぜか。つまり、GameManagerのなかでGameManagerを探すのはどういうことか。

--A **<>内はコンポーネント**（ゲームオブジェクトに関連付けるもの。機能を追加する。スクリプトもコンポーネントの１種。「ボタン機能」「物理演算機能」「衝突判定機能」「エフェクト機能」「サウンド機能」などがコンポーネントにある。つまりコンポーネントにない足りない部分をスクリプトで書いて対応する。）**の型を表している。**

```:2
private GameObject gameManager;  //ゲームマネージャー　これは後々でGameManagerを取得するのだが、その器となるものである。

	// Use this for initialization
	void Start () {
		//ゲームマネージャーを取得
		gameManager=GameObject.Find("GameManager"); //メンバー変数gameManagerにGameManagerゲームオブジェクトを記録
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}

	//ドラッグ処理
	void OnMouseDrag(){
		if (gameManager.GetComponent<GameManager> ().isBallMoving == false) {
			//位置を取得
			float x = Input.mousePosition.x;
			float y = Input.mousePosition.y;
			float z = 100.0f;
			//位置を変換してオブジェクトの座標に指定
			transform.position = Camera.main.ScreenToWorldPoint (new Vector3 (x, y, z));
		}
	}
```

１番目はgameManagerという入れ物をつくって、Findメソッドにより**GOのGameManagerをgameManagerに入れている。そしてこれは、**Unity画面でスクリプトをAddComponentした空のGOに、参照元としてHierarchyのGOをアタッチした状態と一緒である。**そのあとのGetcomponentでは、**[Componentの派生クラス.GetComponent<コンポーネントの型>()]**という構文に従って、**gameManager.GetComponent<GameManager>().~~~**という形になっている。

２番めはvoid Start{}でgameManagerという入れ物（メンバー変数）を作っている。これは、毎回void OnMouseDrag()のときに参照していては動作が重くなるからだ。だから最初に１度だけ参照し、それをメンバー変数に記録している。

---

```
//ドラッグ処理
	void OnMouseDrag(){
		if (gameManager.GetComponent<GameManager> ().isBallMoving == false) {
			//位置を取得
			float x = Input.mousePosition.x;
			float y = Input.mousePosition.y;
			float z = 100.0f;
			//位置を変換してオブジェクトの座標に指定
			transform.position = Camera.main.ScreenToWorldPoint (new Vector3 (x, y, z));
		}
	}
```

float型で変数x,y,zにそれぞれ値を代入している。Inpputクラスを利用している。メンバー変数のmousePositionからはマウスポインタの位置や１本指でタッチしているときの座標をとりだすことができる。
ただし、この座標は**画面の左下を（０，０）とするピクセル単位のスクリーン座標であるので、カメラが持つScreenToWorldPointメソッドを利用してGOが使用するワールド座標に変換する**

```:fromUnityOfficaill_[Input.mousePosition]
現在のマウスの位置のピクセル座標（読み取り専用）

画面やウィンドウの左下は (0, 0) です。 画面やウィンドウの右上は (Screen.width, Screen.height) です。

Note: Input.mousePosition reports the position of the mouse even when it is not inside the Game View, such as when Cursor.lockState is set to CursorLockMode.None. When running in windowed mode with an unconfined cursor, position values smaller than 0 or greater than the screen dimensions (Screen.width,Screen.height) indicate that the mouse cursor is outside of the game window.

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    public GameObject particle;
    void Update()
    {
        if (Input.GetButtonDown("Fire1"))
        {
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            if (Physics.Raycast(ray))
                Instantiate(particle, transform.position, transform.rotation);
        }
    }
}
```

```:Camera.ScreenToWorldPoint
Transform position のスクリーン座標からワールド座標に変換します。

Screenspace is defined in pixels. The bottom-left of the screen is (0,0); the right-top is (pixelWidth,pixelHeight). The z position is in world units from the camera.

// Convert the 2D position of the mouse into a
// 3D position.  Display these on the game window.

using UnityEngine;

public class ExampleClass : MonoBehaviour
{
    void OnGUI()
    {
        Vector3 p = new Vector3();
        Camera  c = Camera.main;
        Event   e = Event.current;
        Vector2 mousePos = new Vector2();

        // Get the mouse position from Event.
        // Note that the y position from Event is inverted.
        mousePos.x = e.mousePosition.x;
        mousePos.y = c.pixelHeight - e.mousePosition.y;

        p = c.ScreenToWorldPoint(new Vector3(mousePos.x, mousePos.y, c.nearClipPlane));

        GUILayout.BeginArea(new Rect(20, 20, 250, 120));
        GUILayout.Label("Screen pixels: " + c.pixelWidth + ":" + c.pixelHeight);
        GUILayout.Label("Mouse position: " + mousePos);
        GUILayout.Label("World position: " + p.ToString("F3"));
        GUILayout.EndArea();
    }
}
```
※Camera.main :   "MainCamera" にタグ付けされている最初の有効なカメラ(読み取り専用)。

**OnMouseDragやOnCollisionEnter2Dメソッドは、その名前のメソッドを書くだけで自動的に呼び出される。Onclickのようなイベントに割り当てる必要もないが、メソッド名を間違えて書いたり、型が違ったりするだけで呼び出されないので注意。エラーも発生しないのだ。**