unity 之 自定義彈出框

  • 2019 年 11 月 3 日
  • 筆記

一、彈出框的搭建:

布局如圖: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;      }  }

 

 

Tags: