[基礎知識]uGUIの操作時に処理を実行する方法

# 基本
とりあえず動かすための方法。
本当にとりあえず動かすためなので、設計的なヤバさは無視する。

### 実装
1. 実装したい処理を持つ関数を作成。

``` cs:Sample.cs
using UnityEngine;

public class Sample : MonoBehaviour
{
    // 必ずpublicにする
    public void Action()
    {
        Debug.Log("アクションが発生しました", this);  
    }
}
```
　
2. 作成したコンポーネントを、シーン内のゲームオブジェクトにアタッチします。
今回はあえて Button とは別のゲームオブジェクトにアタッチしています。
![スクリーンショット 2018-11-28 21.39.05.png](https://qiita-image-store.s3.amazonaws.com/0/67270/9489288a-be54-0e3d-84e2-04a830ec0054.png)
3. 関数を呼び出す側に、関数を登録するエリアを作ります。
今回は Button なので Button(Script) 内の OnClick() の欄になります。
![スクリーンショット 2018-11-28 21.45.37.png](https://qiita-image-store.s3.amazonaws.com/0/67270/2206fb77-5937-e6d8-14ff-9a6f1d268d38.png)
4. 2 でコンポーネントをアタッチした**ゲームオブジェクト**を、3 で作成したエリアの None(Object) にドラッグ＆ドロップします。
![スクリーンショット 2018-11-28 21.45.48.png](https://qiita-image-store.s3.amazonaws.com/0/67270/db5cb08f-234b-2891-5891-4f6e4d08c9a2.png)
5. 今設定した場所の右にある No Function と書いてある項目をクリックし、その中から呼び出したい関数を選択します。
![スクリーンショット 2018-11-28 21.45.56.png](https://qiita-image-store.s3.amazonaws.com/0/67270/6c338c7b-3c62-b7e9-67ee-e53710e56541.png)

### 実行
今回の場合、以下のような文がConsoleタブに表示されればよい。  
![スクリーンショット 2018-11-28 22.10.17.png](https://qiita-image-store.s3.amazonaws.com/0/67270/3a094e71-3a6b-aee7-fd88-a6239dd440ca.png)

# 応用
基本的な実装の他にも可能な設定方法。

### 応用1 引数つきの関数を、値を指定して実行する
引数つきの関数を登録することもできる。

```cs:Sample.cs
using UnityEngine;

public class Sample : MonoBehaviour
{
	public void Action( string value )
	{
		Debug.Log(value, this);
	}
}
```
先ほどと同じ関数名で、引数に string型 の値を設定できる関数を作成。
同じ手順で登録しようとすると、今回は()内に string と書かれた関数が表示される。
![スクリーンショット 2018-11-28 22.30.58.png](https://qiita-image-store.s3.amazonaws.com/0/67270/4532f513-894b-08da-7a74-a4df99efc1c4.png)
選択すると関数名の下に、引数と同じ型の値を入れられる枠ができる。
![スクリーンショット 2018-11-28 22.31.08.png](https://qiita-image-store.s3.amazonaws.com/0/67270/cc7fe082-39b2-d6d9-243f-9cad191a113e.png)
枠に適当な値を設定し実行する事で、関数に値を渡すことができる。
![スクリーンショット 2018-11-28 22.31.21.png](https://qiita-image-store.s3.amazonaws.com/0/67270/30006e4a-7857-10ac-3758-c1f08b10081b.png)
![スクリーンショット 2018-11-28 22.49.08.png](https://qiita-image-store.s3.amazonaws.com/0/67270/38167672-67e5-89af-a718-05cb40f13a51.png)

### 応用2 各コンポーネントのもつ Value を渡して実行する
Toggle や Slider といった一部のコンポーネントは何かしらの型の Value を持っているものがあります。
それらの型と一致する引数をもった関数を登録する事で、それぞれのコンポーネントが持つ Value を関数に渡して実行することができます。
今回は Slider を使用して確認します。  
Slider(Script) を見ると Button 同様、関数を登録できる場所があります。
Button の時は OnClick() であったのに対し、 Slider は OnValueChanged( **Single** ) と引数部に型が書かれています。
※ Single とは float の事をさします。float は Single のエイリアス(別名)です。

![スクリーンショット 2018-11-28 23.05.47.png](https://qiita-image-store.s3.amazonaws.com/0/67270/425618e8-8880-fa84-1049-7142981ed450.png)

この引数部の型と同じ引数の型を持った関数を作り、登録しようとすると、選択項目に特殊な欄が出てきます。

``` cs:Sample.cs
public class Sample : MonoBehaviour
{
	public void Action( float value )
	{
		Debug.Log(value, this);
	}
}
```
![スクリーンショット 2018-11-28 23.13.53.png](https://qiita-image-store.s3.amazonaws.com/0/67270/5f0d6a5c-7ac7-4d6a-0659-23ba1a76fdbb.png)
先ほどまでとは違い、関数名に () がついていません。
こちらを選択することで、引数に Slider のもつ Value を渡すことができます。
![スクリーンショット 2018-11-28 23.22.16.png](https://qiita-image-store.s3.amazonaws.com/0/67270/1497984e-24ab-0a06-4d0d-2242f5521e87.png)
※Slider の設定をデフォルトのまま実行した場合の実行結果。

### 応用3 スクリプト上から実装する
ここまで紹介した方法では、関数をpublicにしないといけない。
しかし設計的にヤバい時もあるため、privateな関数か、ラムダ式で処理を渡したい場合もある。


``` cs:Sample.cs
using UnityEngine.UI;    // UI関連コンポーネントを使うのに必要

public class Sample : MonoBehaviour
{
    [SerializeField]
    private Button _button;

    void Start()
    {
        // privateな関数を渡す場合
        _button.onClick.AddListener(OnClickAction);

        // ラムダ式で渡す場合
        _button.onClick.AddListener(() => Debug.Log("ラムダ式"));
    }

    private void OnClickAction(){ Debug.Log("privateなメソッド"); }
}
```
この方法には幾つかのメリットがある。
1. １つのゲームオブジェクトで管理が出来るようになるため、エディタ上で設定する手間が減る。
2. UIに割り当てた処理を、実行中に変更したり、増やしたりできる。
3. 基礎～応用2までの事は全部これで出来る。
4. 関数の名前を考える手間が減る。(ラムダ式の場合)
他の書き方もあるが~~正直面倒臭いし、宗教戦争が始まるので~~手間が増えたり、少々見づらくなったりするので、2つだけ紹介した。


# 補足
- C# 7に対応していれば、ローカル関数も使用可能。
- デフォルトで **Runtime Only** と書かれている場所は、どのタイミングで呼ばれるかの設定をする場所。
  - Off  
実行されない。
  - Editor And Runtime  
シーン実行時、またはシーン未実行時に Value を書き換えたとき。
  - Runtime Only  
シーン実行時のみ。

# 実行確認環境
- Unity [2018.2.17f1 以上]