【Unity】ダイアログボックスを表示する #3

投稿者: | 2021-01-02

右上のボタンで消せるダイアログボックスを作ってみました。今回はボタンを押したとき処理が毎回同じです。

ダイアログボックスを表示する #1の方法でレイアウトを決めてプレハブ化しておきます。一番上にはスクリプトをつけています。

using UnityEngine;
using UnityEngine.UI;

public class DialogBox : MonoBehaviour
{
    public void SetUp(string text, string leftButtonText, string rightButtonText, UnityEngine.Events.UnityAction leftButtonAction, UnityEngine.Events.UnityAction rightButtonAction)
    {
        // メインのテキストにtextを入れる
        transform.GetChild(0).GetComponent<Text>().text = text;

        // 左ボタンのテキストにleftButtonTextを入れる
        transform.GetChild(1).GetChild(0).GetChild(0).GetComponent<Text>().text = leftButtonText;

        // 右ボタンのテキストにrightButtonTextを入れる
        transform.GetChild(1).GetChild(1).GetChild(0).GetComponent<Text>().text = rightButtonText;

        // 左ボタンのOnClickにメソッドを入れる
        transform.GetChild(1).GetChild(0).GetComponent<Button>().onClick.AddListener(leftButtonAction);

        // 右ボタンのOnClickにメソッドを入れる
        transform.GetChild(1).GetChild(1).GetComponent<Button>().onClick.AddListener(rightButtonAction);
    }

    public void SetUp(string text)
    {
        // ☓ボタンのOnClickにメソッドを入れる
        transform.GetChild(0).GetChild(0).GetComponent<Button>().onClick.AddListener(() => Notification.GetInstance().DestroyDialog(this.gameObject));

        // テキストにtextを入れる
        transform.GetChild(1).GetChild(0).GetComponent<Text>().text = text;
    }


}

同じ名前のメソッドが2つありますが引数リストが違います。それによってどちらのメソッドが呼ばれるか決まります。今回は下の引数が一つのものを使います。

ボタンをクリックしたときのメソッドはラムダ式で書いています。このスクリプトがついたオブジェクトを引数に渡して別のメソッドを呼びます。

ダイアログボックスを生成するクラスに、生成と削除のメソッドを作っています。

[SerializeField] DialogBox dialogBoxPrefab;
bool IsDisplayingDialog;

public void ShowDialog(string text, string leftButtonText, string rightButtonText, UnityEngine.Events.UnityAction leftButtonAction, UnityEngine.Events.UnityAction rightButtonAction)
{
    // ダイアログ表示中でないとき
    if (!IsDisplayingDialog)
    {
        IsDisplayingDialog = true; // 表示中にする

        // ダイアログボックスを作成
        GameObject g = Instantiate(dialogBoxPrefab.gameObject, canvas.transform);

        // テキストとメソッドを設置絵
        g.GetComponent<DialogBox>().SetUp(text, leftButtonText, rightButtonText, leftButtonAction, rightButtonAction);

        DisplayMenuOperation.GetInstance().LockPlayer(); // プレイヤー操作をロック

    }
}

[SerializeField] DialogBox dialogBox3Prefab;

// こちらを使う
public void ShowDialog(string text)
{
    // ダイアログ表示中でないとき
    if (!IsDisplayingDialog)
    {
        IsDisplayingDialog = true; // 表示中にする

        // ダイアログボックスを作成
        GameObject g = Instantiate(dialogBox3Prefab.gameObject, canvas.transform);

        // テキストとメソッドを設置絵
        g.GetComponent<DialogBox>().SetUp(text);

        DisplayMenuOperation.GetInstance().LockPlayer(); // プレイヤー操作をロック

    }
}

public void DestroyDialog()
{
    // ダイアログボックスを検索
    GameObject[] dialogs = GameObject.FindGameObjectsWithTag("Dialog");

    // すべて削除
    foreach(GameObject dialog in dialogs)
    {
        Destroy(dialog);
    }

    // 表示中でなくする
    IsDisplayingDialog = false;

    // プレイヤー操作を解放
    DisplayMenuOperation.GetInstance().ReleasePlayer();
}

// こちらを使う
public void DestroyDialog(GameObject dialog)
{
    // ダイアログを削除
    Destroy(dialog);

    // 表示中でなくする
    IsDisplayingDialog = false;

    // プレイヤー操作を解放
    DisplayMenuOperation.GetInstance().ReleasePlayer();
}

どちらもメソッドをオーバーロードしています。今回はボタンをクリックしたときの処理が決まっているので、生成するときの引数はテキストだけです。削除するオブジェクトも引数で渡せます。

別のクラスから簡単に生成メソッドを呼べます。

if (Input.GetKeyDown(KeyCode.L))
{
    Notification.GetInstance().ShowDialog("右上の☓をクリックすると消えます。");
}

コメントを残す

メールアドレスが公開されることはありません。