【uGUI】Canvasを使ってButtonクリックで表示・非表示できるUI（枠だけ）を作る

# 概要
いい加減、UnityでのUIの実装方法を勉強する必要が出てきたので、テスト実装を行いました。そのデモです。
本当に枠だけの簡単な実装です。

これまでChat GPT等（のAPI）から得たテキストをConsoleに表示していましたが、Buildしてアプリケーションにしたときに、Chat履歴を画面上に表示（非表示）できるようにしたいですし、各種設定画面も必要です。

Canvasの使い方については、たくさんわかりやすい解説があるので、ここでは特に説明はしていませんが、参考になった資料については最後にまとめています。

![Canvas_test - SampleScene - Windows, Mac, Linux - Unity 2022.3.6f1 _DX11_ 2024-02-05 22-57-01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3604990/cb6bae4c-d81d-7647-3f95-a6bd0a76aa33.gif)

# 開発環境
Windows 10
Unity 2022.3.6f1
Api Compatibility Level .NET Standard 2.1

# 使用したパッケージ
特になし

# 実装
### GameObjectの配置
GameObject>UI>Canvasを追加し、同じ要領でButtonやScroll Viewなどのオブジェクトも追加します。
準備したGameObjectは以下の５つです。

* Settingsを表示するPanel
* Chat Logsを表示するScroll View
    * 横スクロールは不要なので、Scroll RectコンポーネントのHorizontalのチェックボックスを外しました。
* Settingsを表示・非表示させるbutton
* Chat Logsを表示・非表示させるbutton
* 後述のスクリプトをセットするEmptyオブジェクト（UIManager）

２つのbuttonのButtonコンポーネントのOn Click()に後述のスクリプトをセットしたUIManagerオブジェクトをセットし、それぞれShowSettingsPanel関数とShowLogsView関数をセットします。
なお、それぞれの関数は後述のスクリプトで定義しています。

### スクリプト

スクリプトの説明は、コメントの通りです。

```csharp:UIManager.cs
using UnityEngine;

public class UIManager : MonoBehaviour
{
    // UI画面のゲームオブジェクトを格納する変数
    // インスペクターウィンドウからゲームオブジェクトを設定する
    [SerializeField] GameObject settingsPanel;
    [SerializeField] GameObject logsView;

    // UI画面の表示状態を格納する変数
    bool isSettingsPanel = false;
    bool isLogsView = false;

    // Start is called before the first frame update
    void Start()
    {
        // 初期化。すべてのUIを画面を非表示にする。
        InactivateAll();
    }

    // Update is called once per frame
    void Update() { }

    // Settings Buttonが押されたときの処理
    public void ShowSettingsPanel()
    {
        if (!isSettingsPanel)
        {
            settingsPanel.SetActive(true);
            isSettingsPanel = true;
        }
        else
        {
            settingsPanel.SetActive(false);
            isSettingsPanel = false;
        }
    }

    // ChatLogs Buttonが押されたときの処理
    public void ShowLogsView()
    {
        if (!isLogsView)
        {
            logsView.SetActive(true);
            isLogsView = true;
        }
        else
        {
            logsView.SetActive(false);
            isLogsView = false;
        }

    }

    // すべてのUI画面を非アクティブにする
    public void InactivateAll()
    {
        settingsPanel.SetActive(false);
        logsView.SetActive(false);
    }
}
```

# TextMeshProの日本語入力について

とこで、TextMeshProに日本語を入力すると「□□□」という表示になりました。どうやらデフォルトで日本語の文字フォントが無いようです。
本来はTextMeshPro用のフォントアセットを作る必要があるようですが、すでに作成し公開してくれている方がいました。

フォントアセットをダウンロードして、日本語を入力したい"TextMeshPro - Text(UI)"コンポーネントのFont Assetに指定するだけで利用できます。

https://github.com/nilpkthmsk/Unity_TMP_Japanese/tree/main

上記のフォントアセット作成までの経緯は以下で確認できます。
https://gist.github.com/kgsi/ed2f1c5696a2211c1fd1e1e198c96ee4?permalink_comment_id=4189457#gistcomment-4189457

# 参考資料
1\. いろいろ、読み漁った中でこちらが一番体系的にまとまっていました。とても参考になります。

https://www.metalbrage.com/UnityTutorials/uGUI/Canvas.html

2\. Canvasの基本は理解したが、実際にUIをデザインするときにどのように作るのかイメージしやすかったのは以下の２つの資料です。

https://xr-hub.com/archives/11782

https://kyoro-s.com/unity-34/

3\. Chat履歴を表示できるようにしたいので、縦スクロールのテキストエリアが必要でした。その参考にしています。

https://zenn.dev/kumatta_ss/articles/9d2ccdf0e432d4

4\. 今回は実装していませんが、将来的にはChat GPT等から取得したテキストをスクリプトを介してテキストエリアのインプとにしなければいけません。以下を参考に実装する予定です。

https://indie-game-creation-with-unity.hatenablog.com/entry/text-mesh-pro-assign-to-text