UnityをC#で超入門してみる #2 ゲームオブジェクトの章

UnityをC#で超入門してみる #1 Unity入門の章
http://qiita.com/hiroyuki_hon/items/0718a50e6569b6c5037a
の続きです。

#目次　超入門#2　ゲームオブジェクトの章
カメラ・移動・変形・削除・色・やりとり

継承関係
Object →　GameObject
Object →　Component 　→ Behaviour

##カメラ

　カメラを調整しよう
　カメラでターゲットを追ってみよう


##ゲームオブジェクト

　ゲームオブジェクトの情報を取得しよう
　スクリプトの有効、無効を設定してみよう
　ゲームオブジェクトのタグをチェックしよう

　Find()でゲームオブジェクトを取得しよう
　スクリプトでコンポーネントを追加しよう
　スクリプトからプリミティブオブジェクトを生成しよう
　　違うプリミティブオブジェクトを表示してみよう
　スクリプトでオブジェクトのtransformを取得しよう
　　個別にx,y,zの値を取得しよう

　移動させてみよう
　Cubeを回転させ、Inspectorから数値を変更しよう
　ゲームオブジェクトを削除しよう
　　自分自身（スクリプト）を削除しよう
　　一定時間後に削除されるようにしよう

　スクリプト色を付けよう
　　色をRGBAで指定しよう
　　ランダムに色をつけてみよう
　他のオブジェクトとのやりとりについて
　自身と違うオブジェクトを取得して操作しよう

　インスタンスを生成しよう
　　nameについて
　ここまでをまとめ
　ボタンクリックでインスタンスを生成しよう
　画面外に出たインスタンスは削除しよう
　　WebCamTextureを使ってみよう

　ゲームオブジェクトを無限に生成しよう
　ゲームオブジェクトを回転させよう
　ボタン押下でゲームオブジェクトを回転させよう

　x秒後にゲームオブジェクトを破棄しよう
　カラーを指定してマテリアルを生成しよう
　プレハブをスクリプトから生成しよう
　触れたものを破壊するオブジェクトを作ろう


##カメラ

#カメラを調整しよう
Sceneビューでカメラの向きを決めます。
カメラを選択状態にして、
GameObject > Align With View
でカメラをSceneビューの視点に設定できます。

#カメラでターゲットを追ってみよう
例えば.LookAtを用いることでカメラなりの向きを追従させることが出来ます。

```csharp
public Transform target;
void Update () {
	transform.LookAt (target);
	}
}
```



##ゲームオブジェクト
Unityは一つ一つの塊をゲームオブジェクトと呼びます。
ゲームオブジェクトにコンポーネントをつけることで
様々な挙動をさせることが出来ます。

ゲームオブジェクトを人、コンポーネントを帽子や
アクセサリーに例えると理解が進みます。

#ゲームオブジェクトの情報を取得しよう

主な変数
transform
rigidbody
camera
renderer
audio
guiText
collider
gameobject
tag

```csharp
	void Start () {
		print(gameObject.transform);
		print(gameObject.audio);
		print(gameObject.guiText);
		print(gameObject.gameObject);
		print(gameObject.tag);
	}
//頭のgameObject.は省略可能
```

#スクリプトの有効、無効を設定してみよう
変数、enabled　を操作することで
スクリプトの有効、無効を設定できます。

```csharp
	void Start () {
		print(enabled);	

		enabled = false;

		print(enabled);

	/*出力 True
	   エディタのゲームオブジェクトのスクリプトのチェックが外れる
	*/出力 False
	}
```

#ゲームオブジェクトのタグをチェックしよう
CompareTag()を用います。

```csharp
//タグがblockだったらコンソールにblockを出す。
if(CompareTag("block")){
	print("block");	
}
```

#Find()でゲームオブジェクトを取得しよう
Find()を用いることで"ゲームオブジェクト名"から
ゲームオブジェクトを取得できます。

適当なPlaneを作ったとします。

```csharp

//適当なGameObject型の変数 gを作成
	public GameObject  g;
		void Start () {

//g に最初に見つかった名前が Plane のゲームオブジェクトを取得する
		g = GameObject.Find("Plane");
		
		print ( g );
		print ( g.audio);
//出力 Plane
//出力 null
}
```


#スクリプトでコンポーネントを追加しよう
例えばScript2を作成してScript1に追加するとします。
以下のようにすることでStart時にScript1にScript2が追加され、
Script2が実行されます。

```csharp
	void Start () {
		gameObject.AddComponent<Script2>();
	}
```




#スクリプトからプリミティブオブジェクトを生成しよう

GameObject cube1 = GameObject.CreatePrimitive(PrimitiveType.Cube); と書いてみます。
![スクリーンショット 2014-01-02 16.49.29.png](https://qiita-image-store.s3.amazonaws.com/0/26030/59897359-dd5d-14ef-00f0-5841eb0efc8a.png)
空のゲームオブジェクトを作って、これにつけて再生すると出ます。
![スクリーンショット 2014-01-02 16.48.52.png](https://qiita-image-store.s3.amazonaws.com/0/26030/53e70f64-8de8-67ee-1e7d-fd1b06b38271.png)

##違うプリミティブオブジェクトを表示してみよう
.Cubeを.Sphere　に書き換えてみます。
![スクリーンショット 2014-01-02 16.54.31.png](https://qiita-image-store.s3.amazonaws.com/0/26030/7372d8d0-3df3-e350-59da-586976395c24.png)
出ました。
![スクリーンショット 2014-01-02 16.53.05.png](https://qiita-image-store.s3.amazonaws.com/0/26030/1fe14af8-cc8a-cf6f-c3a0-58c328a1e41f.png)
このようにしてプリミティブオブジェクトをスクリプトで生成することが可能です。


#スクリプトでオブジェクトのtransformを取得しよう

Unity内の全てのオブジェクトはtransformというプロパティを持っており、
これから位置や角度等を取得することが可能です。
例えばこう書きます。
Debug.Log(transform.position);
![スクリーンショット 2014-01-02 18.54.19.png](https://qiita-image-store.s3.amazonaws.com/0/26030/11e47893-7ad9-ab7b-4726-b67c67dcf544.png)
このスクリプトをつけて再生すると、transform.position がコンソールに出力されます。
このようになります。
![スクリーンショット 2014-01-02 18.56.05.png](https://qiita-image-store.s3.amazonaws.com/0/26030/768593fb-ff5f-5fed-9a76-ef4150b7b55a.png)

Inspectorにあるtransformの数値の簡略化されたものが表示されています。
![スクリーンショット 2014-01-02 18.57.13.png](https://qiita-image-store.s3.amazonaws.com/0/26030/ce5f105c-5bf2-7571-ed37-e9ceeff4a58e.png)

##個別にx,y,zの値を取得しよう
個別にx,y,zの値を取得することも可能です。
Debug.Log(transform.localPosition.x);
Debug.Log(transform.localPosition.y);
Debug.Log(transform.localPosition.z);　と書きます。
![スクリーンショット 2014-01-02 19.13.31.png](https://qiita-image-store.s3.amazonaws.com/0/26030/66a0d6eb-61b5-63ca-c869-e20644bb0f02.png)

すると、このように別々に取得出来ます。
![スクリーンショット 2014-01-02 19.12.08.png](https://qiita-image-store.s3.amazonaws.com/0/26030/aaf31dac-2e84-cf49-a783-6fe9fd7f5bc5.png)


#移動させてみよう
こう書きます。
![スクリーンショット 2014-01-02 21.44.00.png](https://qiita-image-store.s3.amazonaws.com/0/26030/3d14ef61-f592-76b2-34b2-86763832b245.png)
これを貼り付けると移動します。

矢印キーで動かしてみます。

```csharp
	public float x = 0.0f;
	public float z = 0.0f;
	
	// Use this for initialization
	void Start () {
	
	}
	
	// Update is called once per frame
	void Update () {

		if (Input.GetKey(KeyCode.RightArrow)) {
		x = 0.2f;
		z = 0.0f;

		}
		if (Input.GetKey(KeyCode.LeftArrow)) {
		x = -0.2f;
		z =  0.0f;
		}

		transform.Translate(x, 0, 0, Space.World);


		if (Input.GetKey(KeyCode.UpArrow)) {
		z = 0.2f;
		x = 0.0f;

		}
		if (Input.GetKey(KeyCode.DownArrow)) {
		z = -0.2f;
		x =  0.0f;
		}

		transform.Translate(0, 0, z, Space.World);
```

#Cubeを回転させ、Inspectorから数値を変更しよう
Cubeを生成し、
transform.Rotate(0, 1, 0); とスクリプトを書きます。
![スクリーンショット 2014-01-02 21.20.59.png](https://qiita-image-store.s3.amazonaws.com/0/26030/219f0124-d8e7-0e18-dfba-9b9f07423730.png)
回ります。

Inspectorから数値を変更出来るようにします。
このように書いてみます。
public float x = 0;
public float y = 0;
public float z = 0;
void Update () {
transform.Rotate(x, y, z);
![スクリーンショット 2014-01-02 21.31.19.png](https://qiita-image-store.s3.amazonaws.com/0/26030/3179dd86-8581-e8ee-63eb-bd4fe0f1dadd.png)
するとInspectorから数値を入力できるようになります。
こうなっています。
![スクリーンショット 2014-01-02 21.32.47.png](https://qiita-image-store.s3.amazonaws.com/0/26030/3ae63689-e4b1-098d-52d2-443971f40d63.png)

#スクリプトでゲームオブジェクトを削除しよう
ゲームオブジェクトを削除します。
Destroy(gameObject);
![スクリーンショット 2014-01-02 17.08.31.png](https://qiita-image-store.s3.amazonaws.com/0/26030/c016aaa9-6cfa-c568-12a1-6f07b43d6d2a.png)
プリミティブのシリンダーを試しに作り、
Destroy(gameObject);　のスクリプトを付けます。
これを再生すると、
![スクリーンショット 2014-01-02 17.14.03.png](https://qiita-image-store.s3.amazonaws.com/0/26030/bdd5ce87-7c81-2399-1c89-85790f33860c.png)
消えます。
![スクリーンショット 2014-01-02 17.16.04.png](https://qiita-image-store.s3.amazonaws.com/0/26030/64e5ea3f-a8e0-e68f-1e70-d7945fcbbf22.png)


##自分自身（スクリプト）を削除しよう
Destroy(this);
これが消えます。
![スクリーンショット 2014-01-02 17.10.42.png](https://qiita-image-store.s3.amazonaws.com/0/26030/a074fe51-a97b-99bd-5833-347f3de92fdc.png)

![スクリーンショット 2014-01-02 17.09.38.png](https://qiita-image-store.s3.amazonaws.com/0/26030/d0c51ced-6bf7-9889-16f1-82647cce6822.png)

##一定時間後に削除されるようにしよう
一定時間後にに消えるように指定します。
以下のように書くと5.0秒で消えます。
5.0の部分を書き換えることで時間を指定出来ます。
Destroy(gameObject, 5.0f);
![スクリーンショット 2014-01-02 17.40.06.png](https://qiita-image-store.s3.amazonaws.com/0/26030/67d32af9-1b1e-372c-b077-f7c55de7a23f.png)



#スクリプトで色を付けよう

試しにCylinderを作成します。
create > Cylinder　です。
![スクリーンショット 2014-01-02 16.58.49.png](https://qiita-image-store.s3.amazonaws.com/0/26030/aa1efdb1-17c3-83a7-00f0-ef13120955aa.png)

renderer.material.color = Color.red;　と書きます。
![スクリーンショット 2014-01-02 17.57.02.png](https://qiita-image-store.s3.amazonaws.com/0/26030/6cc55d1b-ae0f-acb2-eda6-f098400333f2.png)
こうなります。
![スクリーンショット 2014-01-02 18.00.37.png](https://qiita-image-store.s3.amazonaws.com/0/26030/15f549c3-75a8-dbb5-1445-d2945a33db07.png)

##色をRGBAで指定しよう
色はRGBAを0.0～1.0の値で指定します。
型はfloat型です。 
第四引数を指定しない場合は、α値が1.0となります。

例えばこう書きます。
Color col = new Color(0.0f, 0.0f, 0.0f, 1.0f);
renderer.material.color = col;

![スクリーンショット 2014-01-02 18.17.32.png](https://qiita-image-store.s3.amazonaws.com/0/26030/ce56f3de-4c9f-0daa-ca58-e09c90fd4ea8.png)
とすると黒になります。
![スクリーンショット 2014-01-02 18.17.21.png](https://qiita-image-store.s3.amazonaws.com/0/26030/ef2d402b-8a81-289b-6ab2-2bd7ab7316f2.png)

緑にしたい場合は
RGBAですから第二引数を1にすれば良いので
Color col = new Color(0, 1, 0, 1);
renderer.material.color = col;　と書いてみます。
![スクリーンショット 2014-01-02 18.28.04.png](https://qiita-image-store.s3.amazonaws.com/0/26030/b464ec17-8cb3-34ee-aa4e-35ea98ab51a2.png)

するとこうなります。
![スクリーンショット 2014-01-02 18.30.21.png](https://qiita-image-store.s3.amazonaws.com/0/26030/0697bb5a-ffce-d81a-cc20-1b5274d0bbb4.png)



##ランダムに色をつけてみよう
Color rand = new Color(Random.value, Random.value, Random.value, 1.0f);
renderer.material.color = rand;
と、書いてみます。
randが変数名です。
![スクリーンショット 2014-01-02 18.07.44.png](https://qiita-image-store.s3.amazonaws.com/0/26030/f0dfff08-be39-8cb5-0f97-25f104c2c1fd.png)
ランダムに色が付きます。
![スクリーンショット 2014-01-02 18.09.50.png](https://qiita-image-store.s3.amazonaws.com/0/26030/f5d649ae-58a2-7fff-4453-72870c47f751.png)
![スクリーンショット 2014-01-02 18.09.42.png](https://qiita-image-store.s3.amazonaws.com/0/26030/48636574-7144-678b-bdfd-cc13c1578952.png)
![スクリーンショット 2014-01-02 18.09.24.png](https://qiita-image-store.s3.amazonaws.com/0/26030/9291b354-06ad-c2a7-12df-d50b8e123441.png)



##他のオブジェクトとのやりとりについて

GetComponent()や、SendMessage("関数名")を用います。



#自身と違うオブジェクトを取得して操作しよう
では名前を利用します。
スクリプトは自分自身をgameObjectから取得できました。
では自身と違うオブジェクトを取得するにはどうすれば良いでしょうか。

まずCubeと空のゲームオブジェクトを作ってみます。
![スクリーンショット 2014-01-02 20.52.32.png](https://qiita-image-store.s3.amazonaws.com/0/26030/784b302f-2774-f0d7-b07f-8758f17ff63b.png)

このように書きます。
GameObject kaiten;

void Start () {}に
kaiten = GameObject.Find("Cube");
	
void Update () {}に
kaiten.transform.Rotate(0, 1, 0);

こうなります。
![スクリーンショット 2014-01-02 20.59.52.png](https://qiita-image-store.s3.amazonaws.com/0/26030/b794c805-3f90-c006-6c04-5324eef05b9d.png)

そしてこれを空のゲームオブジェクトに貼付ます。
そして再生をすると
![スクリーンショット 2014-01-02 21.01.28.png](https://qiita-image-store.s3.amazonaws.com/0/26030/20b255c3-d970-2c4a-93ba-7bce7d897156.png)
回ります。

回転の制御は
kaiten.transform.Rotate(0, 1, 0);　です。

このように　GameObject.Find("名前");　を用いることで
自分自身以外のオブジェクトから操作を行うことが可能になります。


#インスタンスを生成しよう

ゲームオブジェクトに、
このように書いたものをつけて再生してみます。
GameObject obj1 = new GameObject();
obj1.name = "neko";
GameObject obj2 = new GameObject("inu");
GameObject obj3 = new GameObject();
![スクリーンショット 2014-01-02 20.27.27.png](https://qiita-image-store.s3.amazonaws.com/0/26030/49f6d232-68c0-690a-8747-ba460da9b7ae.png)

するとこれが、
![スクリーンショット 2014-01-02 20.28.51.png](https://qiita-image-store.s3.amazonaws.com/0/26030/111eb16f-8587-72ea-215e-1facccc8f229.png)

こうなります。
![スクリーンショット 2014-01-02 20.28.42.png](https://qiita-image-store.s3.amazonaws.com/0/26030/edd409f8-7c0a-b8ae-1835-f44872c101cf.png)

inu と neko と　New Game Object のゲームオブジェクト生成されています。
このことから、インスタンスを生成した時、
後から名前をつける(obj1.name = "neko";)ことも可能であるし、
同時に名前を付けることも出来るし、名無しで生成することも可能であることが分かります。

##nameについて
ところで、ゲームオブジェクトの名前については
nameで取得出来ます。
今まではDebug.Logを用いてきましたが、今回はprintを使用してみます。
printも文字列などの表示に使えます。
print(name);　と書いたスクリプトをMainCameraとCubeにつけてみます。
![スクリーンショット 2014-01-02 20.37.21.png](https://qiita-image-store.s3.amazonaws.com/0/26030/4afa6f37-2e86-58b9-b34a-f11c6d67d588.png)
名前が取得出来ました。
![スクリーンショット 2014-01-02 20.41.58.png](https://qiita-image-store.s3.amazonaws.com/0/26030/b36b0fba-75c4-a2cc-f39d-3593c560171e.png)


#ここまでをまとめ
さてそれでは、ここまでを一度まとめます。

プロジェクトを新規に開きます。
![スクリーンショット 2014-01-02 22.16.48.png](https://qiita-image-store.s3.amazonaws.com/0/26030/987f16f6-7fd8-b35b-1af7-47a75a845204.png)

ここまでのものを詰め込んで色々と作ってみます。
![スクリーンショット 2014-01-02 22.52.10.png](https://qiita-image-store.s3.amazonaws.com/0/26030/2bd82922-77f8-efc4-f38e-32cb76ba5f27.png)

再生するとこうなりました。
![スクリーンショット 2014-01-02 22.51.27.png](https://qiita-image-store.s3.amazonaws.com/0/26030/79a48482-750a-844b-6693-0e6ce1452b94.png)
Cubeが回転したり、ランダムで色が付いたり、スクリプトでオブジェクトが生成されたり、
時間が経つとオブジェクトが消えたり、コンソールに文字列が表示されたりといったことが
出来るようになりました。

#ボタンクリックでインスタンスを生成しよう
GameObjectのターゲットを作成しCubePrefabをエディタから設定します。
Input.GetMouseButtonDown(0)　0＝左クリックでインスタンスを生成します。
Rigidbodyを付けておくことで自動落下します。

```csharp
public GameObject CubePrefab;

	// Update is called once per frame
	void Update () {
		if(Input.GetMouseButtonDown(0)){
			Instantiate(CubePrefab);
		}
	}
}
```

#画面外に出たインスタンスは削除しよう
OnBecameInvisible()のオーバーライド関数を使うことで
カメラの不可視状態になった時の処理を表現出来ます。
Cubeのプレハブにつけることで、クリックで生成したオブジェクトを
カメラから外れたら自動で破棄することが出来ます。

```csharp
//カメラから不可視になったら
void OnBecameInvisible(){
//デストロイ
	Destroy(gameObject);
	}
```

WebCamTextureを使うことで
カメラの映像をゲームオブジェクトに貼り付けることが出来ます。

```csharp
	void Start () {
		 WebCamTexture webcamTexture = new WebCamTexture();
    		    renderer.material.mainTexture = webcamTexture;
    		    webcamTexture.Play();	
	}
```

#ゲームオブジェクトを無限に生成しよう

```csharp

using UnityEngine;
using System.Collections;
 
//指定したゲームオブジェクトを無限スポーンさせるスクリプト
public class InfinitySpawn : MonoBehaviour
{
 
//発生するオブジェクトをInspectorから指定する用
  public GameObject spawnObject;
//発生間隔用
  public float interval = 3.0f;
 
 
  void Start () {
//コルーチンの開始
    StartCoroutine("Spawn");
  }
 
  IEnumerator Spawn() {
//無限ループの開始
    while(true){
  //自分をつけたオブジェクトの位置に、発生するオブジェクトをインスタンス化して生成する
      Instantiate(spawnObject, transform.position, Quaternion.identity);
      yield return new WaitForSeconds(interval);
    }
  }
 
}
```

#ゲームオブジェクトを回転させよう

```csharp

//つけたゲームオブジェクトを回転させるスクリプト
public class TransformRotate : MonoBehaviour {
 
	public float rotateX = 0.0f,
		     rotateY = 1.0f,
		     rotateZ = 0.0f;
 
	void Update () 
	{
		transform.Rotate(rotateX, rotateY, rotateZ);
	}
}

```

#ボタン押下でゲームオブジェクトを回転させよう

```csharp
public class GetMouseButtonRotate : MonoBehaviour {
 
	public int mouseButtonDownSetting = 1;
	
	public float  rotateAngleX = 0;
	public float  rotateAngleY = 90;
	public float  rotateAngleZ = 0;
 
	void Update () 
	{
		if ( Input.GetMouseButtonDown(mouseButtonDownSetting) )
	            {
	            	transform.Rotate(rotateAngleX, rotateAngleY, rotateAngleZ); 
	            }
	}
}

```

#x秒後にゲームオブジェクトを破棄しよう

```csharp

public class GameObjectDestroy : MonoBehaviour 
{
  public float desTime = 3.0f;
  
	void Start()
	{
//3.0秒後にゲームオブジェクトを破棄する
		Destroy(gameObject, desTime);
	}
}

```

#カラーを指定してマテリアルを生成しよう

```csharp

public class ColorMaterialMake : MonoBehaviour
{
	void Start () 
	{
//0.0f～1.0fで指定　Color(R,G,B,α);
  Color col = new Color(0.0f, 0.0f, 1.0f, 1.0f);
	renderer.material.color = col;
	}
}

```

#プレハブをスクリプトから生成しよう

```csharp

public class PrefabInstantiateCS : MonoBehaviour 
{
	public GameObject PrefabX;
	
	void Start ()
	{
		Instantiate(this.PrefabX, new Vector3(0, 0, 0), Quaternion.identity);
	}
}
```

#触れたものを破壊するオブジェクトを作ろう

```csharp

public class UnityOnTriggerEnterDestroyCS : MonoBehaviour
{
	void OnTriggerEnter(Collider other)
	{	
		Destroy(gameObject);
	}
}

```


#つづきます
UnityでC#を超入門してみる #3　計算の章
http://qiita.com/hiroyuki_hon/items/3326206dcedb4e5013d4