【Unity】折り畳み機能（アコーディオンメニュー）付きUIの作り方

#1　折り畳み機能とは
こういうもののこと↓↓

![スクリーンショット (93).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233990/3e8d1c5a-0f82-3674-4b4a-4bee2e724bba.gif)

buttonを押すと下に出てきて、もう一回押すと収納される、みたいな。
下に出したとき、これに合わせて、そのさらに下にあった要素も下に下がってくれる、といったもの。
語彙力がなくて申し訳ない…。

#2　準備
縦一列に要素を並べるScroll Viewでの使用を想定している。
こういうのができていたら、前提となる状況の理解としては問題ない。

![screenshot3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233990/834ca82f-4da1-5ee1-b8fa-f561e80affde.gif)

ちゃんと説明をすると…
①Canvas、Canvasの子にScroll Viewを設置
②縦にスクロールできたらいいので、Scrollbar Horizontalは削除！
③Scrollbar Horizontalの削除で発生した不都合なところを諸々調整していく
<img width="700" src="https://1.bp.blogspot.com/-6XAZiLsxPI8/YJHum_qTftI/AAAAAAAAAUQ/tqLCo89bs-AdKOYWVQ4YaUPq74rfBc_2wCNcBGAsYHQ/s1086/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B%252872%2529_LI.jpg">

<img width="700" src="https://1.bp.blogspot.com/-LjFeOLsfF70/YJHv7Xl1F_I/AAAAAAAAAUY/5TdwobwQgMY7eiVP7fmV9FOra-H_ElR1QCNcBGAsYHQ/w678-h396/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B%252873%2529_LI.jpg">

④Contentオブジェクトの各種コンポーネントの追加・変更
　この辺は人によってどんな感じにするか好みがあると思うのですが、私はこんな感じですね。

　Content Size Fitterコンポーネントをつけて垂直フィットをPreferred Sizeに、Vertical Layout Groupをつけて諸々調整、あとはいい感じにRect Transformを弄りました。

<img width="700" alt="ファイル名" src="https://1.bp.blogspot.com/-pZnq6gRa4rE/YJHxFFtXmNI/AAAAAAAAAUg/mKK_jvFxH0EXU4B71b69yzmyiDPNzhSHACNcBGAsYHQ/w583-h767/%25E3%2582%25B9%25E3%2582%25AF%25E3%2583%25AA%25E3%2583%25BC%25E3%2583%25B3%25E3%2582%25B7%25E3%2583%25A7%25E3%2583%2583%25E3%2583%2588%2B%252876%2529.png">

私はこんな感じで作ったのですが、ほかのブログとかを見てるとMaskコンポーネントを手ずから、能動的につけておられる方もいるみたいですね。
私の使っているUnityのバージョンだと、Viewpointというオブジェクトに最初からついてるのですが、もしどこにもなかったらそのあたりに付与されることをおすすめします。

#3　実装方法
UIの配置だが、まずScroll ViewのContentに空オブジェクトを配置する。
その空オブジェクトにImageを二つ、うち一つのImageの子にButtonを一つ配置。

![スクリーンショット (91).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233990/1389ee93-635e-6954-192e-a55459b94c30.png)

今回は、折り畳み部分に該当するImageのUIの色を、わかりやすく赤色にしてみた。

後は一番上の空オブジェクトに、いくつかコンポーネント追加。

![スクリーンショット (92).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1233990/137c061f-4bf5-8e09-09c3-a07d674c1622.png)

Content Size Fitterをつける意味が気になる方は、先ほど挙げたブログを2ページまでじっくり読んでほしい。
ざっくりいうと、子オブジェクトに合わせて親のアンカーを弄れるようにしないと、折り畳み部分が下のオブジェクトと重なったりしてしまうから。

UIの細かい配置は個々お任せで。
私はButtonを右端に寄せてみた。

#4　スクリプト
後はこのスクリプトを空オブジェクトにアタッチすれば完成。
Buttonを180度回転させるプログラムも組んであるが、不要ならば消してほしい。

```c#:FoldingSystem.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class FoldingSystem : MonoBehaviour
{
    //折り畳み部分を取得
    GameObject FoldinfImage;
    //折り畳み部分を表示するか非表示にするか
    bool OpenFold = false;
    //ボタンの画像を回転
    RectTransform button;

    VerticalLayoutGroup contentLayout;

    void Start()
    {
        FoldinfImage = transform.Find("Image2").gameObject;
        button = transform.Find("Image/Button").GetComponent();

        contentLayout = GameObject.Find("Content").GetComponent();
    }

    void Update()
    {
        
    }

    public void OnClickSetInfo()
    {
        if (OpenFold)
        {
            button.localRotation = Quaternion.Euler(0, 0, -90);
            FoldinfImage.SetActive(false);

            StartCoroutine("LayoutRenewal");

            OpenFold = false;
        }
        else
        {
            button.localRotation = Quaternion.Euler(0, 0, 90);
            FoldinfImage.SetActive(true);

            StartCoroutine("LayoutRenewal");

            OpenFold = true;
        }
        contentLayout.enabled = false;
        contentLayout.enabled = true;
    }

    IEnumerator LayoutRenewal()
    {
        //1フレーム停止
        yield return null;

        //再開後の処理
        contentLayout.enabled = false;
        contentLayout.enabled = true;
    }
}
```

要するに、ContentオブジェクトのVertical Layout Groupをオンオフして、レイアウトを再構築させるような処理。

以上！