SliderとInputFieldのどちらでもCubeを回せるようにする

![SS 192.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/a41cd967-f549-8677-1efa-2e99bf69518d.png) 頭がこんがらがるのでメモ


#やること
[前回記事](https://qiita.com/Ninagawa_Izumi/items/96f316d417d825cc1137)の続きです。
タイトル通り、UnityのSliderとInputFieldの両方から、同じをCubeを回せるようにします。InputFieldに値を入力したときに、Cubeが回転するだけでなく、Sliderにも反映するようにします。
自分が全忘却した時の備えとしてのメモです。
前回記事を読んだ人、もしくはUnityでスクリプトをアタッチできる人が対象です。

# 素材の準備

まず、**キャンバス、スライダー、テキスト、インプットフィールド、キューブ、空のオブジェクト（名前は"ParamMaster"にする)**の６つを用意します。
階層は図のようにします。
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/77df4ce5-8e0c-38c2-ca34-51d7c89e7543.png">

作成した各オブジェクトについて、Game画面をみながらインスペクターのTransform-Pos Yの値を変更して、全ての要素が見えるように移動させます。
（下図のPosYの値の例は、Slider:0, Text:50, InputField:30, Cube:3）

<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/17f19e60-44ec-87d1-d737-0048a5943f44.png">

そして、これから作成するスクリプトをアタッチしていきます。



### ① ParamMaster用のスクリプト

空のオブジェクトであるParamMasterにアタッチするスクリプトです。
ParamMasterは、オブジェクトのパラメータを統合的に管理できるようにするための自作のスクリプトです。（Unityにそういう機能があるわけではありません。）
スライダーやインプットフィールドから書き換えられるpublicな変数を置いておき、
それをCubeの回転確度に反映させます。

```c#:ParamMaster.cs
using UnityEngine;

public class ParamMaster : MonoBehaviour
{
    public float open_value = 0; //publicな変数を設定
}
```
スクリプトをオブジェクトのParamMasterにアタッチします。


### ② Cube用のスクリプト

ParamMasterの変数open_valueを参照し、Cubeの回転確度に設定します。

```c#:CubeOp.cs
using UnityEngine;

public class CubeOp : MonoBehaviour
{
    GameObject paramaster;

    void Start()
    {
        paramaster = GameObject.Find("ParamMaster"); //①のオブジェクトを見つける
    }

    void Update()
    {
        ParamMaster script = paramaster.GetComponent<ParamMaster>(); //見つけたオブジェクトのスクリプトを指定
        Vector3 rot = this.transform.localEulerAngles;
        rot.y = -script.open_value;
        this.transform.localEulerAngles = rot;
    }
}

```
Cubeオブジェクトにアタッチします。


### ③ Slider用のスクリプト

スライダーの値をParamMasterに書き込むスクリプトです。

```c#:SliderOp.cs
using UnityEngine;

public class SliderOp : MonoBehaviour
{
    GameObject paramaster;
    public void SendSliderValue(float newValue)
    {
        ParamMaster script = paramaster.GetComponent<ParamMaster>(); //見つけたオブジェクトのスクリプトを指定
        script.open_value = newValue;
    }

    void Start()
    {
        paramaster = GameObject.Find("ParamMaster"); //スクリプト①のオブジェクトを見つける
    }
}
```
Slierオブジェクトにスクリプトをアタッチします。

その後でSlierオブジェクトの設定もしておきます。
Min Valueを-180、Max Valueを180に設定します。
また、On Value Changedの設定を、Runtime Only、その下のボックスにSliderオブジェクトをアタッチします。
右のプルダウンから SliderOP - SendSliderValue を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/669eecc9-370b-e0fb-bdd6-ee8065372ab0.png" width = 400>



### ④ InputField用のスクリプト

InputFieldの値をParamMasterに書き込むスクリプトです。
数字以外の文字には反応しないようにしています。

```c#:InputFieldOp.cs
using UnityEngine;
using UnityEngine.UI;
using System; //convertを使うために必要

public class InputFieldOp : MonoBehaviour
{
    GameObject parammaster;
    InputField inputField;
    Slider slider;

    void Start()
    {
        inputField = GameObject.Find("InputField").GetComponent<InputField>();
        parammaster = GameObject.Find("ParamMaster");
        slider = GameObject.Find("Slider").GetComponent<Slider>();
    }

    public void IfPushEnter(string _)
    {
        //エンターが押されたら調べる（誤動作防止）
        Debug.Log(inputField);
        if (Input.GetKey(KeyCode.Return))
        {
            //InputFieldからテキスト情報を取得する
            string value = inputField.text;

            //入力されたものが数字かどうか判断する
            bool result = float.TryParse(value, out float _);
            if (result != false)
            {
                ParamMaster script = parammaster.GetComponent<ParamMaster>(); //見つけたオブジェクトのスクリプトを指定
                script.open_value = Convert.ToSingle(value);
                slider.value = script.open_value;
            }
            else
            {
                Debug.Log("Input Error");
            }
            inputField.text = ""; //入力フォームのテキストを空にする
        }
    }
}
```

InputFieldオブジェクトにスクリプトをアタッチします。

InputFieldオブジェクトの設定は、
RuntimeOnlyを選択し、下のボックスにInputFieldオブジェクトをアタッチ。
また、右のプルダウンから InputFieldOP - IfPushEnter を選択します。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/717ae2b4-cf3b-67cf-8131-e0acb718501f.png" width = 400>


### ⑤ Text用のスクリプト

ParamMasterの数値を参照し、表示します。


```c#:TextOp.cs
using UnityEngine;
using UnityEngine.UI;

public class TextOp : MonoBehaviour
{
    public GameObject value_display = null; // Textオブジェクト
    GameObject parammaster;

    void Start()
    {
        parammaster = GameObject.Find("ParamMaster"); //①のオブジェクトを見つける
    }

    void Update()
    {
        ParamMaster script = parammaster.GetComponent<ParamMaster>(); //見つけたオブジェクトのスクリプトを指定
        Text display_text = value_display.GetComponent<Text>();
        display_text.text = (script.open_value).ToString();
    }
}
```
Textオブジェクトにアタッチし、
インスペクターの"Value_display"の欄にTEXTオブジェクトをアサインします。


# 完成・実行

画面上部の三角ボタンからプログラムを実行します。
スライダーの操作に連携して、キューブが回転すると同時に、テキストの数値も更新されます。
さらに、インプットフィールドに数値を入力してエンターを押すと、その角度がキューブとスライダーに反映されます。

![Meridian_Cube_qiita.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/565043/e868bf59-04d9-3f64-d70b-9420cca07f3d.gif)


# つぎやること
テキストの表示はインプットフィールド内で完結してコンパクトなUIにしていきたいです。
また、外部からのデータが来た際にも対応できるような仕組みにしていきたいです。