今天介绍游戏在使用Unity进行游戏开发时,会遇到很多弹出的提示框,如果把这些弹出框全部放在场景中,那显然是不现实的,所以查询了网络上的一些博客,整理了思路,封装了一个MessageBox的类,新手上路,如有错误,或有更好的解决方案,请告知~~
1.首先先看一下效果,以及调用方式
通常弹出框会有三种形式,分别为一个按钮,两个按钮以及等待多久时间销毁的
using UnityEngine;
using MessageBoxNS;
public class MessageBoxTest : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
if (Input.GetKeyDown(KeyCode.A))
MessageBox.ShowOverTimeMessageBox("MessageBox", "当前时间" + System.DateTime.Now, 1, () => { Debug.Log("销毁"); });
if (Input.GetKeyDown(KeyCode.B))
MessageBox.ShowConfirmMessageBox("MessageBox", "当前时间" + System.DateTime.Now, "好的", () => { Debug.Log("销毁"); });
if (Input.GetKeyDown(KeyCode.C))
MessageBox.ShowConfirmAndCancleMessageBox("MessageBox", "当前时间" + System.DateTime.Now, "知道了", "快走开");
}
}
这里利用一个枚举来定义,上述所说的三种弹出框的形式
public enum ShowMessageBoxType
{
/// <summary>
/// 只有一个按钮
/// </summary>
Confirm,
/// <summary>
/// 两个按钮
/// </summary>
ConfirmAndCancle,
/// <summary>
/// 根据时间自动销毁
/// </summary>
OverTime
}
新建MessageBox类,用于实例化弹出框的Prefab,以及一些参数关联,通过构造函数来生成预制体,代码上注释写的都很清楚,唯一一点要说的就是第三种显示方式(时间到了自动销毁),预先写了一个OverTimeMessageBoxCallBack.cs文件,利用Unity来控制时间以及回调!
using System;
using UnityEngine;
namespace MessageBoxNS
{
public class OverTimeMessageBoxCallBack : MonoBehaviour
{
public Action DestroyCallBack;
public float timer;
private void Start()
{
Invoke("ExecuteCallBack", timer);
}
private void ExecuteCallBack()
{
DestroyCallBack?.Invoke();
Destroy(this.gameObject);
}
}
}
public class MessageBox
{
/// <summary>
/// 弹出框类型
/// </summary>
public ShowMessageBoxType MessageBoxType { get; set; }
/// <summary>
/// 提示信息
/// </summary>
public string HintInfo { get; set; }
/// <summary>
/// 确定按钮显示文字
/// </summary>
public string ConfirmStr { get; set; }
/// <summary>
/// 取消按钮显示文字
/// </summary>
public string CancleStr { get; set; }
/// <summary>
/// 预制体路径
/// </summary>
public string PrefabPath { get; set; }
/// <summary>
/// 消失时间
/// </summary>
public float HideTime { get; set; }
/// <summary>
/// 确定按钮回调
/// </summary>
public Action ConfirmAction { get; set; }
/// <summary>
/// 取消按钮回调
/// </summary>
public Action CancleAction { get; set; }
/// <summary>
/// 时间到了之后销毁弹出框的回调
/// </summary>
public Action OverTimeAction { get; set; }
/// <summary>
/// 生成的Box
/// </summary>
public GameObject Box = null;
/// <summary>
/// 利用类构造函数来实例化Prefab,再定义一个函数当然也是可以的
/// </summary>
/// <param name="messageBoxType">提示框类型</param>
/// <param name="prefabPath">预制体路径</param>
/// <param name="hintInfo">提示信息</param>
/// <param name="confirmStr">确定按钮显示文字</param>
/// <param name="cancleStr">取消按钮文字</param>
/// <param name="confirmAction">确定按钮回调</param>
/// <param name="cancleAction">取消按钮回调</param>
/// <param name="overTimeAction">计时销毁回调</param>
/// <param name="hideTime">销毁时间</param>
public MessageBox(ShowMessageBoxType messageBoxType, string prefabPath, string hintInfo, string confirmStr, string cancleStr, Action confirmAction, Action cancleAction, Action overTimeAction, float hideTime)
{
this.MessageBoxType = messageBoxType;
this.PrefabPath = prefabPath;
this.HintInfo = hintInfo;
this.ConfirmStr = confirmStr;
this.CancleStr = cancleStr;
this.ConfirmAction = confirmAction;
this.CancleAction = cancleAction;
this.OverTimeAction = overTimeAction;
this.HideTime = hideTime;
//实例化提示框,并设置初始参数
Box = UnityEngine.Object.Instantiate(Resources.Load<GameObject>(PrefabPath), GameObject.Find("Canvas").transform);
Box.transform.localPosition = Vector3.zero;
Box.transform.localScale = Vector3.one;
Button confirmBtn;
Button cancelBtn;
Text hintInfoTxt;
BindindToData(Box, out confirmBtn, out cancelBtn, out hintInfoTxt);
switch (messageBoxType)
{
case ShowMessageBoxType.Confirm:
cancelBtn.gameObject.SetActive(false);
confirmBtn.gameObject.SetActive(true);
confirmBtn.transform.localPosition = new Vector3(0, confirmBtn.transform.localPosition.y, confirmBtn.transform.localPosition.z);
break;
case ShowMessageBoxType.ConfirmAndCancle:
confirmBtn.gameObject.SetActive(true);
cancelBtn.gameObject.SetActive(true);
break;
case ShowMessageBoxType.OverTime:
confirmBtn.gameObject.SetActive(false);
cancelBtn.gameObject.SetActive(false);
Box.AddComponent<OverTimeMessageBoxCallBack>();
Box.GetComponent<OverTimeMessageBoxCallBack>().DestroyCallBack = overTimeAction;
Box.GetComponent<OverTimeMessageBoxCallBack>().timer = hideTime;
break;
default:
break;
}
}
/// <summary>
/// 绑定数据到实例化出的Box面板
/// </summary>
/// <param name="box"></param>
private void BindindToData(GameObject box, out Button confirmBtn, out Button cancelBtn, out Text hintInfoTxt)
{
//获取
confirmBtn = box.transform.Find("confrimBtn").GetComponent<Button>();
cancelBtn = box.transform.Find("cancelBtn").GetComponent<Button>();
hintInfoTxt = box.transform.Find("HintInfo").GetComponentInChildren<Text>();
//赋值
hintInfoTxt.text = HintInfo;
confirmBtn.GetComponentInChildren<Text>().text = ConfirmStr;
cancelBtn.GetComponentInChildren<Text>().text = CancleStr;
confirmBtn.onClick.AddListener(() => { ConfirmAction?.Invoke(); ClosePanel(box); });
cancelBtn.onClick.AddListener(() => { CancleAction?.Invoke(); ClosePanel(box); });
}
/// <summary>
/// 清除面板
/// </summary>
/// <param name="timer"></param>
private void ClosePanel(GameObject box, float timer = 0)
{
UnityEngine.Object.Destroy(box, timer);
}
/// <summary>
/// 实例化通用提示框(等待HideTime之后,销毁提示框)
/// </summary>
/// <param name="prefabName">预制体名字这里路径写死了,大家可以根据自己需要修改修改</param>
/// <param name="hintInfo">提示信息</param>
/// <param name="hideTime">销毁时间</param>
/// <param name="overTimeAction">销毁回调</param>
public static void ShowOverTimeMessageBox(string prefabName, string hintInfo, float hideTime = 2, Action overTimeAction = null)
{
MessageBox boxInfo = new MessageBox(ShowMessageBoxType.OverTime, "MessageBox/" + prefabName, hintInfo, null, null, null, null, overTimeAction, hideTime);
}
/// <summary>
/// 实例化通用提示框(单按钮确定,销毁提示框)
/// </summary>
/// <param name="prefabName">预制体名字这里路径写死了,大家可以根据自己需要修改修改</param>
/// <param name="hintInfo">提示信息</param>
/// <param name="confirmStr">单按钮显示文字</param>
/// <param name="comfirmAction">按钮回调</param>
public static void ShowConfirmMessageBox(string prefabName, string hintInfo, string confirmStr, Action comfirmAction = null)
{
MessageBox boxInfo = new MessageBox(ShowMessageBoxType.Confirm, "MessageBox/" + prefabName, hintInfo, confirmStr, "", comfirmAction, null, null, 1);
}
/// <summary>
/// 实例化通用提示框(双按钮确定,销毁提示框)
/// </summary>
/// <param name="prefabName">预制体名字这里路径写死了,大家可以根据自己需要修改修改</param>
/// <param name="hintInfo">提示信息</param>
/// <param name="confirmStr">确定按钮显示文字</param>
/// <param name="cancleStr">取消按钮显示文字</param>
/// <param name="comfirmAction">确定按钮回调</param>
/// <param name="cancleAction">取消按钮回调</param>
public static void ShowConfirmAndCancleMessageBox(string prefabName, string hintInfo, string confirmStr, string cancleStr, Action comfirmAction = null, Action cancleAction = null)
{
MessageBox boxInfo = new MessageBox(ShowMessageBoxType.ConfirmAndCancle, "MessageBox/" + prefabName, hintInfo, confirmStr, cancleStr, comfirmAction, cancleAction, null, 1);
}
}
调用函数当然就是MessBox类下面的三个静态函数啦,这里要说的是,预制体的结构是要有限制的
因为代码里是通过这些名字查找各个组件的~~
#手动滑稽,第一次写博客,希望在自己积累知识的同时,能帮助到大家~