【Unity】UnityScreenNavigatorで「Yes」「No」ボタンのあるモーダルから、どれを押したか取得する処理を作る

# はじめに
画面遷移OSSライブラリ「Unity Screen Navigator」の学習を兼ねて、「Yes」「No」ボタンの付いたモーダルを使用して、どのボタンが押されたかの結果を外部に送信して、結果を出力するサンプルを作成してみました。

UnityScreenNavigatorに関しては下のリンクを参照してください。

https://github.com/Haruma-K/UnityScreenNavigator


# 作成物
1. 「Open Modal」ボタンを押すことでモーダルが開く
1. モーダル内の「Yes」「No」どちらかを押す
1. 上部のテキストが押したボタンによって変わる


![Movie_002.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553099/9810084a-d681-1802-345d-52c87c70f66c.gif)

# 環境
Unity : 2022.3.9f
UnityScreenNavigator : 1.6.5

# 実装

## 画面UIの用意
モーダルを起動するボタンGUIと結果出力用のテキストGUIを用意する。

![UnityScreenNavigator_ss_00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553099/d2814c93-2497-034d-9dfb-7c0a460c39d8.png)

## ModalContainerの用意
「ModalContainer」コンポーネントを付けたGameobjectをCanvas以下に配置する。また、モーダルの表示順がTopになるようにCanvasの一番下に入れている。

![UnityScreenNavigator_ss_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553099/aaa973cc-c7d6-1130-a788-89c8c27a176f.png)


## Modalプレハブの用意
「Yes」「No」ボタンが付いたModalプレハブ「YesNoModal」を作成して、Resourcesフォルダに入れる。

![UnityScreenNavigator_ss_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553099/e54f8dfe-0b2c-9713-9c04-93ba7767991c.png)


## スクリプトの用意
Modalプレハブ「YesNoModal」の先頭オブジェクトにアタッチするModalクラスを継承した「YesNoModal」クラスを作成する。ボタンイベントを外部から設定できるように、「OnClickYesButton」「OnClickNoButton」ボタンイベントを用意する。

```cs:YesNoModal.cs
using System.Collections;
using UnityEngine;
using UnityEngine.UI;
using UnityScreenNavigator.Runtime.Core.Modal;

public class YesNoModal : Modal
{
    [SerializeField]
    private Button _yesButton = null;

    [SerializeField]
    private Button _noButton = null;


    public Button.ButtonClickedEvent OnClickYesButton => _yesButton.onClick;
    public Button.ButtonClickedEvent OnClickNoButton => _noButton.onClick;

}

```
最後に全体を統括する、MonoBehaviourクラスを継承した「ModalTest」クラスを作成し、ヒエラルキーに登録して、インスペクター上でTextオブジェクトをアタッチすれば完成です。

![UnityScreenNavigator_ss_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3553099/9afa8c41-c9a3-c1ca-0d0a-28ddb094a4b9.png)


OpenModal関数内で、modalの呼び出しを行なっており、onLoadのコールバックでYesNoModalクラスを取得をして、各ボタンのイベントを登録して、押下情報を取得する。
Yesボタンが押されれば、OnClick_YesButton()が実行され、NOボタンが押されたらOnClick_NoButton()が実行される。

```cs:ModalTest.cs
using System.Collections;
using UnityEngine;
using UnityScreenNavigator.Runtime.Core.Modal;

public class ModalTest : MonoBehaviour
{
    [SerializeField]
    private TMPro.TextMeshProUGUI _resultText = null;

    private ModalContainer _modalContainer = null;
    // Start is called before the first frame update
    void Start()
    {
        _modalContainer = ModalContainer.Find("ModalContaner");
        _resultText.text = "Not SelectButton";
    }

    //Button Event : Modalの表示
    public void OnClick_OpenModal()
    {
        StartCoroutine(OpenModal());
    }

    //Button Event : YESボタンが押された
    public void OnClick_YesButton()
    {
        _modalContainer.Pop(true);
        _resultText.text = "Select Yes Button";
    }

    //Button Event : NOボタンが押された
    public void OnClick_NoButton()
    {
        _modalContainer.Pop(true);
        _resultText.text = "Select No Button";

    }

    //Modalの表示
    private IEnumerator OpenModal()
    {
        var handle = _modalContainer.Push("YesNoModal", true, onLoad : x =>
        {
            var yesNoModal = (YesNoModal)x.modal;
            //各ボタンに実行時の処理を登録
            yesNoModal.OnClickYesButton.AddListener(OnClick_YesButton);
            yesNoModal.OnClickNoButton.AddListener(OnClick_NoButton);
        });
        yield return handle;
    }
}

```

# 参考

https://light11.hatenadiary.com/entry/2021/10/27/221801

https://github.com/Haruma-K/UnityScreenNavigator/blob/master/README_JA.md