ダイアログボックスを表示する #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);
}
}
テキストやボタンを探すときはTransform.GetChildメソッドの引数に、ヒエラルキーウィンドウで表示される順番を渡します。
階層ごとに、0から始まり下方向へ番号が1ずつ増えます。
UIでポップアップウィンドウを作るで作った管理クラスに、このダイアログボックスを表示するメソッドを書きました。
[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(); // プレイヤー操作をロック
}
}
public void DestroyDialog()
{
// ダイアログボックスを検索
GameObject[] dialogs = GameObject.FindGameObjectsWithTag("Dialog");
// すべて削除
foreach(GameObject dialog in dialogs)
{
Destroy(dialog);
}
// 表示中でなくする
IsDisplayingDialog = false;
// プレイヤー操作を解放
DisplayMenuOperation.GetInstance().ReleasePlayer();
}
他のダイアログが表示中でない時にプレハブをインスタンス化してテキストなどを設定するメソッドを呼びます。この時に、メニューとカーソルを表示してプレイヤーの移動回転を止めるの方法でプレイヤーの操作をロックしています。
メニューの開閉メソッドでプレイヤー操作のロック/ロック解除もしていますが、メソッドを分けました。
public void LockPlayer()
{
playerScript.LockPosition(true); // プレイヤーの位置を固定
cameraScript.LockRotation(true); // 回転を固定
cameraScript.LockCursor(false); // カーソルロックを解除
}
public void ReleasePlayer()
{
playerScript.LockPosition(false); // プレイヤーの移動を自由にする
cameraScript.LockRotation(false); // 回転を自由にする
cameraScript.LockCursor(true); // カーソルをロック
}
そして、他のクラスから、ダイアログを表示するメソッドを呼びます。今回はボタンのOnClickに床の色を変えるメソッドと、ダイアログを削除するメソッドを入れています。
void ChangeFloorColor()
{
// 床を探す
GameObject[] floors = GameObject.FindGameObjectsWithTag("Floor");
// 色を赤にする
foreach(GameObject floor in floors)
{
floor.GetComponent<MeshRenderer>().material.SetColor("_BaseColor", Color.red);
}
// ダイアログボックスを削除
Notification.GetInstance().DestroyDialog();
}
// Update is called once per frame
void Update()
{
if(Input.GetKeyDown(KeyCode.L))
{
Notification.GetInstance().ShowDialog("床の色を変えますか?", "はい","いいえ", ChangeFloorColor, Notification.GetInstance().DestroyDialog);
}
これでダイアログボックスを表示して、クリックするボタンによって処理を変えられました。