一、弹出框的搭建:
布局如图:Message为整个父物体,并且添加UiMessage代码。panel为遮罩。
MessageBox为整个提示框,Panel为标题,ok为确定按钮,cancel为取消按钮,retry为重试按钮,Text为提示框的文字。
注意大小写,后面代码会根据名称进行获取对应组建。

效果如下:


二、MessageBox代码:
要说明的都在代码中注释了。仿照Windows的提示框功能,如果功能不足可自行添加。例如关闭按钮、显示图标等。
- using System;
- public enum DialogResult
- {
- Ok,
- OKCancel,
- RetryCancel,
- YesNo,
- YesNoCancel
- }
- public static class MessageBox
- {
- /// <summary>
- /// true表示模态框
- /// </summary>
- public static bool type;
- //三个委托,分别为三个按钮的点击运行事件
- public static Action clickOk;
- public static Action clickRetry;
- public static Action clickCancel;
- public static DialogResult dialogResult;
- //标题
- public static string headText;
- //文本
- public static string text;
- //状态。用于显示或隐藏弹出框
- public static bool state;
- /// <summary>
- ///重试按钮点击事件
- /// </summary>
- public static void onClickRetry()
- {
- state = false;
- clickRetry?.Invoke();
- clickRetry = null;
- }
- /// <summary>
- /// 取消按钮点击事件
- /// </summary>
- public static void onClickCancel()
- {
- state = false;
- clickCancel?.Invoke();
- clickCancel = null;
- }
- /// <summary>
- /// 确定按钮点击事件
- /// </summary>
- public static void onClickOk()
- {
- state = false;
- clickOk?.Invoke();
- clickOk = null;
- }
- /// <summary>
- /// 显示
- /// </summary>
- /// <param name="_text">内容</param>
- /// <param name="_head">标题</param>
- /// <param name="dialog">样式</param>
- /// <param name="type">模式</param>
- public static void Show(string _text,string _head,DialogResult _dialog, bool _type = true)
- {
- text = _text;
- headText = _head;
- dialogResult = _dialog;
- type = _type;
- state = true;
- }
- public static void Show(string _text,string _head,bool _type = true)
- {
- text = _text;
- headText = _head;
- dialogResult = DialogResult.Ok;
- type = _type;
- state = true;
- }
- public static void Show(string _text, bool _type = true)
- {
- text = _text;
- headText = "信息";
- dialogResult = DialogResult.Ok;
- type = _type;
- state = true;
- }
- }
三、UiMessage代码:
添加到Message物体上。用于控制弹出框的显示等功能。
- using UnityEngine;
- using UnityEngine.UI;
- public class UiMessage : MonoBehaviour
- {
- public Button ok;
- public Button cancel;
- public Button retry;
- /// <summary>
- /// 遮罩
- /// </summary>
- public GameObject panel;
- public Text headText;
- public Text text;
- /// <summary>
- /// 弹出框
- /// </summary>
- private GameObject messageBox;
- private void Awake()
- {
- messageBox = gameObject.transform.GetChild(1).gameObject;
- ok = messageBox.transform.Find("ok").GetComponent<Button>();
- cancel = messageBox.transform.Find("cancel").GetComponent<Button>();
- retry = messageBox.transform.Find("retry").GetComponent<Button>();
- panel = gameObject.transform.Find("panel").gameObject;
- text = messageBox.transform.Find("Text").GetComponent<Text>();
- headText = messageBox.transform.GetChild(0).Find("head").GetComponent<Text>();
- //将提示框居中显示
- messageBox.transform.position = new Vector3(Screen.width / 2 - messageBox.GetComponent<RectTransform>().rect.width / 2,
- Screen.height / 2 + messageBox.GetComponent<RectTransform>().rect.height / 2, 0);
- init();
- }
- private void OnEnable()
- {
- init();
- }
- private void init()
- {
- ok.onClick.AddListener(MessageBox.onClickOk);
- cancel.onClick.AddListener(MessageBox.onClickCancel);
- retry.onClick.AddListener(MessageBox.onClickRetry);
- text.text = MessageBox.text;
- headText.text = MessageBox.headText;
- //根据传递的参数,进行样式的显示
- switch (MessageBox.dialogResult)
- {
- case DialogResult.Ok:
- ok.gameObject.SetActive(true);
- cancel.gameObject.SetActive(false);
- retry.gameObject.SetActive(false);
- break;
- case DialogResult.OKCancel:
- ok.gameObject.SetActive(true);
- cancel.gameObject.SetActive(true);
- retry.gameObject.SetActive(false);
- break;
- case DialogResult.RetryCancel:
- ok.gameObject.SetActive(true);
- cancel.gameObject.SetActive(true);
- retry.gameObject.SetActive(true);
- break;
- case DialogResult.YesNo:
- ok.transform.GetChild(0).GetComponent<Text>().text = "是";
- cancel.transform.GetChild(0).GetComponent<Text>().text = "否";
- ok.gameObject.SetActive(true);
- cancel.gameObject.SetActive(true);
- retry.gameObject.SetActive(false);
- break;
- case DialogResult.YesNoCancel:
- ok.transform.GetChild(0).GetComponent<Text>().text = "是";
- cancel.transform.GetChild(0).GetComponent<Text>().text = "否";
- ok.gameObject.SetActive(true);
- cancel.gameObject.SetActive(true);
- retry.gameObject.SetActive(true);
- break;
- }
- }
- private void Update()
- {
- panel.SetActive(MessageBox.type);
- gameObject.SetActive(MessageBox.state);
- }
- }
三、显示框的调用:
此处调用可以自行设置一个按钮,在其点击事件中注册调用即可。
笔者使用项目中的方式进行演示。具体不做说明。调用方式已给出。
特别注意:由于UiMessage调用了MessageBox的方法,所以必须先初始化MessageBox的数据。使用什么就初始化什么。笔者使用了ok、cancel按钮(默认不初始化模式,即为模态框,不初始化DialogResult即为只显示ok按钮),所以注册了相应的点击事件(委托)。最后显示弹出框(整个包含遮罩和弹出框)。

三、运行结果:

三、弹出框可拖拽移动:
将DragManage添加到MessageBox物体上面。(如果你想让ui物体可拖拽,对其添加DragManage即可实现)
笔者就不做演示了
- using UnityEngine;
- using UnityEngine.EventSystems;
- /// <summary>
- /// 只是用来处理拖拽
- /// </summary>
- public class DragManage : MonoBehaviour, IDragHandler, IBeginDragHandler, IEndDragHandler
- {
- private Vector3 offect;
- public void OnBeginDrag(PointerEventData eventData)
- {
- offect = Input.mousePosition - transform.position;
- }
- public void OnDrag(PointerEventData eventData)
- {
- transform.position = Input.mousePosition - offect;
- }
- public void OnEndDrag(PointerEventData eventData)
- {
- transform.position = Input.mousePosition - offect;
- }
- }