Unity スクリプトはじめた。

# GameObject

なんかUnityを勉強する羽目になった。
まずは、GameObjectから押さえていこうと思う

## GameObjectを生成する
```csharp
using UnityEngine;

public class Sample : MonoBehaviour
{
    private void Start()
    {
        var obj1 = new GameObject();
        obj1.name = "myobject1"
        obj1.AddComponent<Ridgebody>();

        // 名前をコンストラクタに渡す
        var obj2 = new GameObject("myobject2");
        obj2.AddComponent<Rigdbody>();

        //名前とコンポーネントをコンストラクタに渡す
        var obj3 = ne GameObject("myobject3", typeof(Rigidbody), typeof(BoxCollider));
    }
}
```

## プリミティブの生成

立方体や球体などの基本的なモデルはプリミティブとして用意されている。プリミティブを生成するには、GameObjectのCreatePrimitive()を使用する

```csharp
using UnityEngine;

public class Example : MonoBehaviour
{
    // Create a plane, sphere and cube in the Scene.

    void Start()
    {
        GameObject plane  = GameObject.CreatePrimitive(PrimitiveType.Plane);

        GameObject cube = GameObject.CreatePrimitive(PrimitiveType.Cube);
        cube.transform.position = new Vector3(0, 0.5f, 0);

        GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        sphere.transform.position = new Vector3(0, 1.5f, 0);

        GameObject capsule = GameObject.CreatePrimitive(PrimitiveType.Capsule);
        capsule.transform.position = new Vector3(2, 1, 0);

        GameObject cylinder = GameObject.CreatePrimitive(PrimitiveType.Cylinder);
        cylinder.transform.position = new Vector3(-2, 1, 0);
    }
}
```

## GameObjectを複製する
UnityEngineのObjectクラスにはInstantiate()というクラスメソッドが用意されており、オブジェクトを複製することができる。
```csharp
using UnityEngine;

public class Example : MonoBehaviour
{
    public GameObject prefab;
    void Start()
    {
        var pos = new Vector3(2, 0, 0);
        var rot = new Vector3(0, 45, 0);
        var origin = GameObject.CreatePrimitive(PrimitiveType.Cube);
        Instantiate(origin, pos, Quaternion.Euler(rot));
    }
}
```

## GameObjectを削除する
ObjectクラスにはInstantiate()の他にもDestroy()メソッドがあり、オブジェクトを削除することができる。
このメソッドが呼び出されると、現在のUpdateループが終わった直後に削除が実行される。また、引数tに遅延時間を指定することもできる。

削除対象がコンポーネントだった場合、コンポーネントが付与されているGameObjectからコンポーネントが削除される。
削除対象がGameObjectだった場合、そのGameObjectとGameObjectに付与されているコンポーネント、子GameObjectが削除される。

```csharp
using UnityEngine;

public class ScriptExample : MonoBehaviour
{
    void DestroyGameObject()
    {
        Destroy(gameObject);
    }

    void DestroyScriptInstance()
    {
        // 自身に設定されているスクリプトを削除
        Destroy(this);
    }

    void DestroyComponent()
    {
        // Rigidbodyコンポーネントを削除する
        Destroy(GetComponent<Rigidbody>());
    }

    void DestroyObjectDelayed()
    {
        // 5秒後にGameObjectを削除
        Destroy(gameObject, 5);
    }

    // When the user presses Ctrl, it will remove the
    // BoxCollider component from the game object
    void Update()
    {
        if (Input.GetButton("Fire1") && GetComponent<BoxCollider>())
        {
            Destroy(GetComponent<BoxCollider>());
        }
    }
}
```

## GameObjectを検索する

GameObjectには名前でオブジェクトを検索できるFind()というメソッドが用意されている。複数のオブジェクトが同じ名前を持つような場合、最初に見つかったものを返す（たぶん）
該当するオブジェクトが見つからない場合はnullを返す。

引数に"右手/人差し指"、"左手/人差し指" いったようにスラッシュ(/)で区切ってやれば、階層を走査して検索することができる。

実行が遅いので、Update毎に呼び出すといった使い方は避けた方がよい。
非アクティブなオブジェクトは検索の対象外。

```csharp
using UnityEngine;
using System.Collections;

// This returns the GameObject named Hand in one of the Scenes.

public class ExampleClass : MonoBehaviour
{
    public GameObject hand;

    void Example()
    {
        // 名前Handを持つオブジェクトを検索.
        hand = GameObject.Find("Hand");

        // 名前Handを持つオブジェクトを検索、ただし階層ビューで親オブジェクトを持たない
        hand = GameObject.Find("/Hand");

        // 名前Handを持つオブジェクトを検索.
        //階層のルート直下からMonster/Armの配下にある
        hand = GameObject.Find("/Monster/Arm/Hand");

        // 名前Handを持つオブジェクトを検索
        // Monster/Armの子オブジェクト
        hand = GameObject.Find("Monster/Arm/Hand");
    }
}

```
## GameObjectをタグ付けする

名前や階層構造だけで管理が難しい場合は、タグを付与して管理することもできる。タグはインスペクタービューの上部に配置されている。




![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7739/56ceca17-1df0-4e3f-9e4d-38346a068ab8.png)

オブジェクトにタグを付与する場合、あらかじめ「Tag and Layers」にタグを登録しておく必要がある。未登録のタグをオブジェクトに付与しようとすると例外がスローされる(UnityException)

```csharp
using UnityEngine;

public class Example : MonoBehaviour
{
    void Start()
    {
        //Set the tag of this GameObject to Player
        gameObject.tag = "Player";
    }
}
```
## タグでGameObjectを検索する

タグでオブジェクトを検索する場合、FindGameObjectsWithTag()メソッドを使用する

```csharp
// Instantiates respawnPrefab at the location
// of all game objects tagged "Respawn".

using UnityEngine;
using System.Collections;

public class ExampleClass : MonoBehaviour
{
    public GameObject respawnPrefab;
    public GameObject[] respawns;
    void Start()
    {
        if (respawns == null)
            respawns = GameObject.FindGameObjectsWithTag("Respawn");

        foreach (GameObject respawn in respawns)
        {
            Instantiate(respawnPrefab, respawn.transform.position, respawn.transform.rotation);
        }
    }
}
```

## レイヤーを使う

GameObjectにはLayerを設定できる、Layerプロパティにはint型の値を入力する必要があるため、LayerMask.NameToLayer()メソッドでレイヤー名から整数に変換する必要がある。

```csharp
// Put the game object in the ignore raycast layer (2)

using UnityEngine;

[ExecuteInEditMode]
public class ExampleClass : MonoBehaviour
{
    void Awake()
    {
        //gameObject.layer uses only integers, but we can turn a layer name into a layer integer using LayerMask.NameToLayer()
        int LayerIgnoreRaycast = LayerMask.NameToLayer("Ignore Raycast");
        gameObject.layer = LayerIgnoreRaycast;
        Debug.Log("Current layer: " + gameObject.layer);
    }
}
```