Unityの冒険04 -基礎編-

## 24.音を鳴らすプログラムを作ってみよう
音はゲームにとって欠かせません。まずは基本の使い方をやってみましょう。
```try24.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //AudioSource型の変数を宣言する
    AudioSource sound;

    void Start()
    {
        //AudioSourceコンポーネントを取得して、変数に格納する
        sound = GetComponent<AudioSource>();

        //音を鳴らす
        sound.Play();
        
    }
}
```
音を出すためには、AudioSourceコンポーネントと音の素材が必要です。音を出すタイミングは、Unityの再生ボタンを押したときに鳴らすとします。

## 25.Dictionaryを使ってみよう
```try25-1.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //Dictionary型を宣言し、string型とint型の順にしてみる
    Dictionary<string, int> player = new Dictionary<string, int>();    

    void Start()
    {
        //Dictionary型のplayer変数に格納する
        player.Add("勇者", 10);

        //取り出してみる
        print(player["勇者"]);
    }
}
```
このようにDictionary型を使うことができる。Dictionaryはコレクションという機能の一つです。もう少しやってみましょう。

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

public class TryCode : MonoBehaviour
{
    //Dictionary型を宣言し、int型とstring型の順にしてみる
    Dictionary<int,string> player = new Dictionary<int, string>();    

    void Start()
    {
        //Dictionary型のplayer変数に格納する
        player.Add(10, "勇者");

        //取り出してみる
        print(player[10]);
    }
}
```
今度は、Dictionary型でint型とstring型の順にデータをセットしてみた。

## 26. キー入力操作で動かすプログラムを作ろう
キー入力についてやってみましょう。キーの入力は、ユーザー側からのタイミングや反応があった場合に処理します。そういった処理はInputクラスを使います。
```try26-1.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    void Update()
    {
        //右キーが "押され続けている間" 処理してね!
        if(Input.GetKey(KeyCode.RightArrow))
        {
            print("右押してます");
        }
    }
}
```
Inputクラスの中で、GetKey関数を使い、「右キーが押され続けているなら」という条件を付け加えました。すると、コンソールウィンドウにはいっぱいメッセージが出てきますね。

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

public class TryCode : MonoBehaviour
{
    void Update()
    {
        //右キーが "押し込まれた一回だけ" 処理してね!
        if(Input.GetKeyDown(KeyCode.RightArrow))
        {
            print("右押してます");
        }
    }
}
```
今度はGetKeyDown関数を使ってみます。これであれば、「右キーをずっと押し続けても一回しか」処理できないようになります。つまり右キーを２回押せば、２回呼び出されるわけです。タイミングは「キーが押し込まれた瞬間」です。

```try26-3.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    void Update()
    {
        //右キーが "押されてキーを離す瞬間一回だけ" 処理してね!
        if(Input.GetKeyUp(KeyCode.RightArrow))
        {
            print("右押してます");
        }
    }
}
```
今度はGetKeyUp関数を使ってみます。これは「キーが押し込まれてキーを離す瞬間の一回だけ」処理するようになります。タイミングが違うわけなんです。


```try26-4.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //float型のspeed変数を宣言する
    float number;

    void Update()
    {
        //GetAxis関数で左右キーが押された(Horizontal)数値をspeed変数に格納する
        speed = Input.GetAxis("Horizontal");

        //位置を移動する
        transform.position = new Vector3(speed, 0, 0);
    }
}
```
少し難しく感じますが、やっていることは左右キーが入力されたら、ゲームオブジェクトを動かすプログラムです。GetAxis関数では入力されたら-1~1の間でfloat型の数値にしてくれます。GetAxisRaw関数もあり、これは-1, 0, 1のどれかになります。

## 27. シーンチェンジをやってみよう
ゲームを仕上げたり、ゲーム中にシーンを切り替えたりするときに欠かせないのがシーンチェンジです。
```TitleScene.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//シーンチェンジに必要な名前空間を追加してね
using UnityEngine.SceneManagement;

public class TitleScene : MonoBehaviour
{
    void Update()
    {
        //スペースキーが押し込まれたら次の処理をしてね
        if(Input.GetKeyDown(KeyCode.Space))
        {
            //方法1: MainSceneというシーン名に切り替えてね
            SceneManager.LoadScene("MainScene");

            //方法2: もし名前空間を使わず直接記述する場合はこちら
            UnityEngine.SceneManagement.SceneManager.LoadScene("MainScene");
        }       
    }
}

```
ゲームを始める際に、一番最初に出てくるのが「スペースキーが押されたら開始する」ものです。TitleSceneからMainSceneへ切り替える。

```MainScene.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//シーンチェンジに必要な名前空間を追加してね
using UnityEngine.SceneManagement;

public class MainScene : MonoBehaviour
{
    void Update()
    {
        //スペースキーが押し込まれたら次の処理をしてね
        if(Input.GetKeyDown(KeyCode.Space))
        {
            //方法1: TitleSceneというシーン名に切り替えてね
            SceneManager.LoadScene("TileScene");

            //方法2: もし名前空間を使わず直接記述する場合はこちら
            UnityEngine.SceneManagement.SceneManager.LoadScene("TitleScene");
        }       
    }
}
```
またMainSceneからTitleSceneへの切り替えも可能です。ただMainSceneからTitleSceneへ切り替わるのは不自然なので、ゲームオーバーになった時にタイトルシーンへ戻るというのが理想ですね。

## 28.ボタンをクリックできるプログラムを作ろう
ボタンを押して実行するものをやってみましょう。UIにてボタンをヒエラルキーに作成します。
```try28.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TryCode : MonoBehaviour
{
    //publicにした好きな関数を作りましょう
    public void ActionClick()
    {
        //コンソールに出力する
        print("ボタンを押したね！");
    }
}
```
このスクリプトをボタンゲームオブジェクトに追加します。
Bottonコンポーネントにて、On ClickのところでRuntime Onlyの部分があります。そこにヒエラルキーのボタンゲームオブジェクトをドラッグ＆ドロップします。そしたら、NoFanctionから上記の作成したスクリプト名を選び、さらにActionClick関数を選択します。これで、再生ボタンから画面上のボタンをクリックするとコンソールにメッセージが出力されるようになります。

## 29.スクリプト内で自分自身のクローンを作ってみよう
クローンとは、同じものを複数作ることです。ゲームであれば、「弾を発射する時」、「同じ敵を複数表示するとき」、「同じ障害物を複数表示するとき」など使用します。
```try29-1.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Good : MonoBehaviour
{
    void Start()
    {
        //gameObject変数で自分自身のクローンを作ってみる
        Instantiate(gameObject);
    }
}
```
これが一番簡単な方法です。Instantiate関数を使います。
```try29-2.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Good : MonoBehaviour
{
    //外部から任意のゲームオブジェクトをアタッチする
    public GameObject bullet;

    void Start()
    {
        //bullet変数をクローンしてみる
        Instantiate(bullet);
    }
}
```
外部からゲームオブジェクトをアタッチして、クローンを作ることができます。
もうちょっとやってみましょう。
```try29-3.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Good : MonoBehaviour
{
    //外部から任意のゲームオブジェクトをアタッチする
    public GameObject bullet;

    void Start()
    {
        //bulletを "位置を指定して"、"回転なし" で、クローンしてね
        Instantiate(bullet, new Vector3(1, 0, 0), Quaternion.identity);
    }
}
```
さて少し難しくなりました。Instantiate関数はそれぞれ引数に割り当てられています。
もう少しわかりやすいようにしてみましょうか。

```try29-4.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Good : MonoBehaviour
{
    //外部から任意のゲームオブジェクトをアタッチする
    public GameObject bullet;

    void Start()
    {
        //bulletを "位置を指定して"、"回転なし" で、クローンしてね
        Instantiate(bullet, new Vector3(1, 0, 0), Quaternion.identity);
        Instantiate(bullet, new Vector3(2, 0, 0), Quaternion.identity);
        Instantiate(bullet, new Vector3(3, 0, 0), Quaternion.identity);
    }
}
```
このように位置を指定することで、きれいに並べることができました。
今度クォータニオンで遊んでみましょう。
```try29-5.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Good : MonoBehaviour
{
    //外部から任意のゲームオブジェクトをアタッチする
    public GameObject bullet;

    void Start()
    {
        //bulletを "位置を指定して"、"回転あり" で、クローンしてね
        Instantiate(bullet, new Vector3(1, 0, 0), Quaternion.Euler(0, 0, 15));
        Instantiate(bullet, new Vector3(2, 0, 0), Quaternion.Euler(0, 0, 30));
        Instantiate(bullet, new Vector3(3, 0, 0), Quaternion.Euler(0, 0, 45));
    }
}
```
少し難しくなりましたが、やっていることは15度ずつ回転を指定して表示するようにしました。