Unityの冒険03 -基礎編-

## 18.他のゲームオブジェクトのスクリプトにアクセスしてみよう
他のゲームオブジェクトについているスクリプトから、データを参照して使いたい場合があるとします。
```try18-used.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Shop : MonoBehaviour
{
    //お店の名前を変数に入れて、どこからでもアクセスできるように設定
    public string shopName = "海辺のお店";

    public string ShopItemList()
    {
        return "ショップアイテムリスト：浅瀬の貝殻";
    }
```
こちらのShopというクラス名のスクリプトは、使われる側です。RPGでプレイヤーが街にやってきて、お店に入る場面を想像しましょう。プレイヤー側はどんなお店で、どういうものが売っているのか知りたい。

```try18-use.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Playder : MonoBehaviour
{
    //Shop型の変数名shopを宣言する
    Shop shop;

    void Start()
    {
        //ゲームオブジェクトShopを見つけ、Shopコンポーネントを取得
        shop = GameObject.Find("Shop").GetComponent<Shop>();

        //Shopスクリプトの変数名を参照する
        print(shop.shopName);

        //Shopスクリプトの関数名(メソッド名)を参照する
        print(shop.ShopItemList());

        //例
        print("プレイヤーは" + shop.shopName + "で" + shop.ShopItemList() + "を手に入れた");
    }
```
ゲームオブジェクトShopに、Shopスクリプトがついている。そしてプレイヤーというゲームオブジェクトでPlayerスクリプトがついている状態。例としてぜひ使ってみてください。


## 19.リストを使ってみよう
リストとは配列の考え方と似ている。
```try19.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //リストを宣言して、中に「数値」のデータを格納する
    List<int> item = new List<int>(){1,2,3,4,5};

    //リストを宣言して、中に「文字列」のデータを格納する
    List<string> playerItems = new List<string>(){"やくそう","ちず","何かの鍵"};

    void Start()
    {
        //itemリストの一番最初のデータを取り出す
        print(item[0]);

        //playerItemリストの一番歳ののデータを取り出す
        print(playerItems[0]);

    }

    void Update()
    {

    }

    //プレイヤーが何かコライダーに触れたらアイテムに格納するための関数
    void OnCollisionEnter(Collision collision)
    {
        //playerItemsリストに格納する
        playerItems.Add(collision.gameObject.name);

        //プレイヤーが触れたゲームオブジェクトを削除する
        Destroy(collision.gameObject);

        //触れたものを含めたリストを確認する
        foreach (string myItem in playerItems)
        {
            print(myItem);
        }
    }  
}
```
ちょっといきなりハードルがグッと上がってしまいました。リストを作成して、後からデータを格納し、全てのデータが入っているか確認するという流れです。このスクリプトを想定しているのは、プレイヤーが何かキーで操作して、プレイヤーが他のコライダーに触れたら、リストに格納します。

## 20. 列挙型を使ってみよう
列挙型は、ある特定の範囲の中でしかデータを扱えないようにしたりするときに使います。
```try20-1.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //列挙型の「目的地」というデータを格納している
    public enum Destination
    {
        Sendai,
        Yamagata,
        Morioka,
        Akita,
        Aomori,
        Hukushima
    }

    void Start()
    {
       //列挙型から取り出して出力してみる
        print(Destination.Sendai);

        print("勇者は" + Destination.Akita + "に行きたい");
    }
}
```
列挙型の名前を宣言して、列挙型の名前とその中にあるデータ名を指定することでアクセスできるようになります。

```try20-2.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //アニメーションを管理する列挙型を作成する
    private enum State
    {
        Idle,
        Walk,
        Jump,
        Run
    }

    //列挙型の変数を宣言して、変数で使えるようにする
    private State state;

    void Start()
    {
        // 初めはIdle状態にする
        state = State.Idle;
        
    }

    void Update()
    {
        //switch文でアニメーションの切り替えを分ける　
        switch (state)
        {
            case State.Walk:
                print("歩いている");
                break;
            case State.Jump:
                print("ジャンプしている");
                break;
            case State.Run:
                print("走っている");
                break;
            default:
                print("アイドル状態");
                break;
        }
    }
}

```
このように、switch文でアニメーションを管理することもできる。

## 21.ゲームオブジェクトを見つけるプログラムを書いてみよう
```try21.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //ゲームオブジェクト型の変数を宣言する
    GameObject search;

    void Start()
    {
        //ゲームオブジェクト名「Player」を探して、変数に代入する
        search = GameObject.Find("Player");

        //確かめる
        print(search);
    }
}

```
Find関数を使って、引数に探し出したいゲームオブジェクト名を指定することができます。

## 22. タグでゲームオブジェクトを探そう
ゲームオブジェクトにタグをつけて、そのタグ名でゲームオブジェクトを探すことができる。
```try22.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //ゲームオブジェクト型の変数を宣言する
    GameObject search;

    void Start()
    {
        //タグ名「Enemy」を探して、変数に代入する
        search = GameObject.FindWithTag("Enemy");

        //確かめる
        print(search.name);
    }
}
```
タグは複数のゲームオブジェクトにつけることができ、ゲームオブジェクトの色分けとして活用できるのがポイントです。

## 23. 複数のアイテムを調べよう
タグの使い方がわかったところで、複数のゲームオブジェクトに同じタグ名が付いたとしましょう。タグによるグループ分けみたいに、複数の敵がいてその敵のゲームオブジェクトのタグに「Enemy」と印をつけておきます。
```try23.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //GameObject型の配列を用意し、enemies変数を宣言します
    GameObject[] enemies;

    void Start()
    {
        //Enemyというタグを調べ、それをenemiesという配列に格納します
        enemies = GameObject.FindGameObjectsWithTag("Enemy");

        //配列から一つ一つ取り出す
        foreach (GameObject enemy in enemies)
        {
            print(enemy.name);
        }
    }
}
```
ちょっとハードルが上がりましたが、FindGameObjectWithTag関数を使うことで簡単にタグの付いているゲームオブジェクトを探すことができます。

```try23-2.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //整数型の変数を宣言する
    int enemies;

    void Start()
    {
        //Lengthプロパティをつけて、enemies変数に格納する
        enemies = GameObject.FindGameObjectsWithTag("Enemy").Length;
        
        print(enemies);
    }
}
```
Lengthプロパティをつけることで、タグの個数を調べることもできる。これは「敵の数」だけでなく、「アイテム個数」を調べるときにも応用できますね。