Unity游戏UI框架(四):模态窗体管理
来源:互联网 发布:淘宝联盟佣金 编辑:程序博客网 时间:2024/06/05 06:58
我们在开发UI窗体时,对于“弹出窗体”往往因为需要玩家优先处理弹出小窗体,则要求玩家不能(无法)点击“父窗体”,这种窗体就是典型的“模态窗体”。在此设计了四种模式类型:完全透明、半透明、低透明度、透明且可以穿透。
完全透明不能穿透
半透明不能穿透
低透明度,不能穿透
模态窗体实现原理
在弹出窗体的后面增加一层“UI遮罩窗体”,当需要弹出特定模态窗体时,脚本自动控制“UI遮罩窗体”的“层级”,把弹出模特窗体与普通窗体之间进行隔离,起到突出显示与遮挡用户点击其他窗体的作用。原理如下图所示:
在上图左边的层级视图中,有一个“_UIMaskPanel”的特殊窗体,这就是“UI遮罩窗体”,在不需要弹出显示的时候,这个窗体是“禁用”状态。 为了更好适用不同开发需求,对于弹出窗体,我们上面定义了关于弹出窗体的不同性质: 完全透明、半透明、低透明度、透明且可以穿透。 这四种类型功能的实现原理是控制“_UIMaskPanel”的颜色数值以及透明度实现的,见下图所示:
说明: 上图右边属性就是“UI遮罩窗体”的属性栏,笔者通过脚本控制Image组件的Color 组件,来实现”模态窗体”的不同显示性质。
原理讲完,贴出控制代码如下:
/// <summary>/// UI遮罩层管理器/// </summary>public class UIMaskMgr : MonoBehaviour{ /// <summary> /// 单例 /// </summary> private static UIMaskMgr _instance = null; /// <summary> /// UI根节点对象 /// </summary> private GameObject _GoCanvasRoot = null; /// <summary> /// UI脚本节点对象 /// </summary> private Transform _TraUiScripts = null; /// <summary> /// 顶层面板:UI根节点对象 /// </summary> private GameObject _GoTopPanel = null; /// <summary> /// 遮罩面板 /// </summary> private GameObject _GoMaskPanel = null; /// <summary> /// UI摄像机 /// </summary> private Camera _UICamera; /// <summary> /// UI摄像机原始的“层深” /// </summary> private float _OriginalUICameralDepth; public static UIMaskMgr GetInstance() { if (!_instance) { _instance = new GameObject("_UIMaskMgr").AddComponent<UIMaskMgr>(); } return _instance; } void Awake() { _GoCanvasRoot = GameObject.FindGameObjectWithTag(SysDefine.SYS_TAG_CANVAS); _TraUiScripts = GameTools.FindTheChildNode(_GoCanvasRoot, SysDefine.SYS_SCRIPTMANAGER_NODE); //把本脚本实例,作为“脚本节点对象”的子节点。 GameTools.AddChildNodeToParentNode(_TraUiScripts, transform); //得到“顶层面板”、“遮罩面板” _GoTopPanel = _GoCanvasRoot; _GoMaskPanel = GameTools.FindTheChildNode(_GoCanvasRoot, SysDefine.SYS_MASKPANEL_NODE).gameObject; //得到UI摄像机原始的“层深” _UICamera = GameTools.FindTheChildNode(_GoCanvasRoot, SysDefine.SYS_UICAMERA_NODE).gameObject.GetComponent<Camera>(); if (_UICamera) { //得到UI摄像机原始“层深” _OriginalUICameralDepth = _UICamera.depth; } else { Debug.Log(GetType() + "/Start()/UI_Camera is Null!,Please Check! "); } } /// <summary> /// 设置遮罩状态 /// </summary> /// <param name="goDisplayUIForms">需要显示的UI窗体</param> /// <param name="lucenyType">显示透明度属性</param> public void SetMaskWindow(GameObject goDisplayUIForms, UIFormLucenyType type = UIFormLucenyType.Lucency) { //顶层窗体下移:SetAsLastSibling:设置为同级最后 _GoTopPanel.transform.SetAsLastSibling(); //启用遮罩窗体以及设置透明度 switch (type) { //完全透明,不能穿透 case UIFormLucenyType.Lucency: _GoMaskPanel.SetActive(true); Color newColor = new Color(1.0f, 1.0f, 1.0f, 0.0f); _GoMaskPanel.GetComponent<Image>().color = newColor; break; //半透明,不能穿透 case UIFormLucenyType.Translucence: _GoMaskPanel.SetActive(true); Color newColor2 = new Color(220 / 255F, 220 / 255F, 220 / 255F, 50 / 255F); _GoMaskPanel.GetComponent<Image>().color = newColor2; break; //低透明,不能穿透 case UIFormLucenyType.ImPenetrable: _GoMaskPanel.SetActive(true); Color newColor3 = new Color(50 / 255F, 50 / 255F, 50 / 255F, 200F / 255F); _GoMaskPanel.GetComponent<Image>().color = newColor3; break; //可以穿透 case UIFormLucenyType.Pentrate: if (_GoMaskPanel.activeInHierarchy) { _GoMaskPanel.SetActive(false); } break; default: break; } //遮罩窗体下移 _GoMaskPanel.transform.SetAsLastSibling(); //显示窗体的下移 goDisplayUIForms.transform.SetAsLastSibling(); //增加当前UI摄像机的层深(保证当前摄像机为最前显示) if (_UICamera) { _UICamera.depth = _UICamera.depth + 100; } } /// <summary> /// 取消遮罩状态 /// </summary> public void CancelMaskWindow() { //顶层窗体上移 _GoTopPanel.transform.SetAsFirstSibling(); //禁用遮罩窗体 if (_GoMaskPanel.activeInHierarchy) { //隐藏 _GoMaskPanel.SetActive(false); } //恢复当前UI摄像机的层深 if (_UICamera != null) { _UICamera.depth = _OriginalUICameralDepth; //恢复层深 } }}
关于上述定义的UIMaskMgr.cs 脚本代码 ,在“BaseUIForm.cs” 中做了封装,使其可以在框架中自动管理,无需框架外客户程序的处理。BaseUIForm.cs 代码如下:
/// <summary>/// UI窗体基类/// </summary>public class BaseUIForm : MonoBehaviour { /// <summary> /// 当前(基类)窗体类型 /// </summary> private UIType _CurrentUIType = new UIType(); /// <summary> /// 属性_当前UI窗体类型 /// </summary> internal UIType CurrentUIType { get { return _CurrentUIType; } set { _CurrentUIType = value; } } /// <summary> /// UI界面显示 /// </summary> public virtual void Display() { this.gameObject.SetActive(true); //设置模态窗体调用(必须是弹出窗体) if (_CurrentUIType.UIForm_Type == UIFormType.PopUp) { UIMaskMgr.GetInstance().SetMaskWindow(this.gameObject, _CurrentUIType.UIForm_LucencyType); } } /// <summary> /// UI界面隐藏(不在“栈”集合中) /// </summary> public virtual void Hiding() { this.gameObject.SetActive(false); //取消模态窗体调用 if (_CurrentUIType.UIForm_Type == UIFormType.PopUp) { UIMaskMgr.GetInstance().CancelMaskWindow(); } } /// <summary> /// UI界面重新显示 /// </summary> public virtual void Redisplay() { this.gameObject.SetActive(true); //设置模态窗体调用(必须是弹出窗体) if (_CurrentUIType.UIForm_Type == UIFormType.PopUp) { UIMaskMgr.GetInstance().SetMaskWindow(this.gameObject, _CurrentUIType.UIForm_LucencyType); } } /// <summary> /// //页面冻结(还在“栈”集合中),窗体显示在其他窗体下面 /// </summary> public virtual void Freeze() { this.gameObject.SetActive(true); }}
以上所讲解的是大体实现思路,还有很多的小细节由于时间关系没有披露,具体的项目后面章节会提供下载
转载地址:刘老师讲Unity
阅读全文
0 0
- Unity游戏UI框架(四):模态窗体管理
- 游戏UI框架设计(四) : 模态窗体管理
- Unity游戏UI框架(三):窗体的层级管理
- 游戏UI框架设计(三) : 窗体的层级管理
- Unity游戏UI框架(九):实现多语言管理
- Unity游戏UI框架(一)
- Unity UI层级管理框架
- Unity游戏UI框架(五):配置管理
- Unity游戏UI框架(六):日志系统
- Unity框架——UI管理
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- Unity 游戏框架搭建 (四) 简易有限状态机
- 游戏框架之UI管理(二)
- Unity游戏UI框架(二):最简版本设计
- Unity游戏UI框架(七):消息传递中心
- Unity游戏UI框架(八):监听事件系统
- Mysql Explain 详解
- picasso框架
- 4.数字与字符串类型
- SHA1算法
- 深度学习网络模型训练中loss为nans的总结
- Unity游戏UI框架(四):模态窗体管理
- Fekit的使用
- 【机房重构】存储过程介绍
- 【脚本语言系列】关于Python并发技术Redis,你需要知道的事
- eclipse配置tomcat
- Python安装gif库:cannot import name 'readGif'解决方法
- 跨域的几种解决方法
- C程序设计进阶week7
- Java实现-N皇后问题1