zoukankan      html  css  js  c++  java
  • 游戏UI框架设计(四) : 模态窗体管理

    游戏UI框架设计(四)

    --模态窗体管理

     

      我们在开发UI窗体时,对于“弹出窗体”往往因为需要玩家优先处理弹出小窗体,则要求玩家不能(无法)点击“父窗体”,这种窗体就是典型的“模态窗体”。在此笔者设计了四种模式类型:完全透明、半透明、低透明度、透明且可以穿透。

        

      (透明不能穿透)

        

        (半透明不能穿透)

        

         (低透明度,不能穿透)

         对于“模态窗体”的基本实现原理是:

        在弹出窗体的后面增加一层“UI遮罩窗体”,当需要弹出特定模态窗体时,脚本自动控制“UI遮罩窗体”的“层级”,把弹出模特窗体与普通窗体之间进行隔离,起到突出显示与遮挡用户点击其他窗体的作用。原理如下图所示:

       

        在上图左边的层级视图中,有一个“_UIMaskPanel”的特殊窗体,这就是“UI遮罩窗体”,在不需要弹出显示的时候,这个窗体是“禁用”状态。 为了更好适用不同开发需求,对于弹出窗体,我们上面定义了关于弹出窗体的不同性质: 完全透明、半透明、低透明度、透明且可以穿透。 这四种类型功能的实现原理是控制“_UIMaskPanel”的颜色数值以及透明度实现的,见下图所示:

      

       说明: 上图右边属性就是“UI遮罩窗体”的属性栏,笔者通过脚本控制Image组件的Color 组件,来实现"模态窗体”的不同显示性质。

       原理讲完,贴出控制代码如下:

     

      1 /***
      2  * 
      3  *    Title: "SUIFW" UI框架项目
      4  *           主题: UI遮罩管理器  
      5  *    Description: 
      6  *           功能: 负责“弹出窗体”模态显示实现
      7  *                  
      8  *    Date: 2017
      9  *    Version: 0.1版本
     10  *    Modify Recoder: 
     11  *    
     12  *   
     13  */
     14 using System.Collections;
     15 using System.Collections.Generic;
     16 using System.Net.Mime;
     17 using UnityEngine;
     18 using UnityEngine.UI;
     19 
     20 namespace SUIFW
     21 {
     22     public class UIMaskMgr : MonoBehaviour {
     23         /*  字段 */
     24         //本脚本私有单例
     25         private static UIMaskMgr _Instance = null;  
     26         //UI根节点对象
     27         private GameObject _GoCanvasRoot = null;
     28         //UI脚本节点对象
     29         private Transform _TraUIScriptsNode = null;
     30         //顶层面板
     31         private GameObject _GoTopPanel;
     32         //遮罩面板
     33         private GameObject _GoMaskPanel;
     34         //UI摄像机
     35         private Camera _UICamera;
     36         //UI摄像机原始的“层深”
     37         private float _OriginalUICameralDepth;
     38 
     39         //得到实例
     40         public static UIMaskMgr GetInstance()
     41         {
     42             if (_Instance==null)
     43             {
     44                 _Instance = new GameObject("_UIMaskMgr").AddComponent<UIMaskMgr>();
     45             }
     46             return _Instance;
     47         }
     48 
     49 
     50 
     51 
     52         void Awake()
     53         {
     54             //得到UI根节点对象、脚本节点对象
     55             _GoCanvasRoot = GameObject.FindGameObjectWithTag(SysDefine.SYS_TAG_CANVAS);
     56             _TraUIScriptsNode = UnityHelper.FindTheChildNode(_GoCanvasRoot, SysDefine.SYS_SCRIPTMANAGER_NODE);
     57             //把本脚本实例,作为“脚本节点对象”的子节点。
     58             UnityHelper.AddChildNodeToParentNode(_TraUIScriptsNode,this.gameObject.transform);
     59             //得到“顶层面板”、“遮罩面板”
     60             _GoTopPanel = _GoCanvasRoot;
     61             _GoMaskPanel = UnityHelper.FindTheChildNode(_GoCanvasRoot, "_UIMaskPanel").gameObject;
     62             //得到UI摄像机原始的“层深”
     63             _UICamera = GameObject.FindGameObjectWithTag("_TagUICamera").GetComponent<Camera>();
     64             if (_UICamera != null)
     65             {
     66                 //得到UI摄像机原始“层深”
     67                 _OriginalUICameralDepth = _UICamera.depth;
     68             }
     69             else
     70             {
     71                 Debug.Log(GetType()+"/Start()/UI_Camera is Null!,Please Check! ");
     72             }
     73         }
     74 
     75         /// <summary>
     76         /// 设置遮罩状态
     77         /// </summary>
     78         /// <param name="goDisplayUIForms">需要显示的UI窗体</param>
     79         /// <param name="lucenyType">显示透明度属性</param>
     80         public void SetMaskWindow(GameObject goDisplayUIForms,UIFormLucenyType lucenyType=UIFormLucenyType.Lucency)
     81         {
     82             //顶层窗体下移
     83             _GoTopPanel.transform.SetAsLastSibling();
     84             //启用遮罩窗体以及设置透明度
     85             switch (lucenyType)
     86             {
     87                     //完全透明,不能穿透
     88                 case UIFormLucenyType.Lucency:
     89                     print("完全透明");
     90                     _GoMaskPanel.SetActive(true);
     91                     Color newColor1=new Color(255/255F,255/255F,255/255F,0F/255F);
     92                     _GoMaskPanel.GetComponent<Image>().color = newColor1; 
     93                     break;
     94                     //半透明,不能穿透
     95                 case UIFormLucenyType.Translucence:
     96                     print("半透明");
     97                     _GoMaskPanel.SetActive(true);
     98                     Color newColor2 = new Color(220/255F, 220/255F, 220/255F, 50/255F);
     99                     _GoMaskPanel.GetComponent<Image>().color = newColor2; 
    100                     break;
    101                     //低透明,不能穿透
    102                 case UIFormLucenyType.ImPenetrable:
    103                     print("低透明");
    104                     _GoMaskPanel.SetActive(true);
    105                     Color newColor3=new Color(50/255F,50/255F,50/255F,200F/255F);
    106                     _GoMaskPanel.GetComponent<Image>().color = newColor3; 
    107                     break;
    108                     //可以穿透
    109                 case UIFormLucenyType.Pentrate:
    110                     print("允许穿透");
    111                     if (_GoMaskPanel.activeInHierarchy)
    112                     {
    113                         _GoMaskPanel.SetActive(false);
    114                     }
    115                     break;
    116 
    117                 default:
    118                     break;
    119             }
    120 
    121 
    122 
    123             //遮罩窗体下移
    124             _GoMaskPanel.transform.SetAsLastSibling();
    125             //显示窗体的下移
    126             goDisplayUIForms.transform.SetAsLastSibling();
    127             //增加当前UI摄像机的层深(保证当前摄像机为最前显示)
    128             if (_UICamera!=null)
    129             {
    130                 _UICamera.depth = _UICamera.depth + 100;    //增加层深
    131             }
    132 
    133         }
    134 
    135         /// <summary>
    136         /// 取消遮罩状态
    137         /// </summary>
    138         public void CancelMaskWindow()
    139         {
    140             //顶层窗体上移
    141             _GoTopPanel.transform.SetAsFirstSibling();
    142             //禁用遮罩窗体
    143             if (_GoMaskPanel.activeInHierarchy)
    144             {
    145                 //隐藏
    146                 _GoMaskPanel.SetActive(false);
    147             }
    148 
    149             //恢复当前UI摄像机的层深 
    150             if (_UICamera != null)
    151             {
    152                 _UICamera.depth = _OriginalUICameralDepth;  //恢复层深
    153             }
    154         }
    155 
    156 
    157     }
    158 }
    View Code

    关于上述定义的UIMaskMgr.cs 脚本代码 ,笔者在“BaseUIForm.cs” 中做了封装,使其可以在框架中自动管理,无需框架外客户程序的处理。BaseUIForm.cs 代码如下:

     1 /***
     2  * 
     3  *    Title: "SUIFW" UI框架项目
     4  *           主题: UI窗体的父类
     5  *    Description: 
     6  *           功能:定义所有UI窗体的父类。
     7  *           定义四个生命周期
     8  *           
     9  *           1:Display 显示状态。
    10  *           2:Hiding 隐藏状态
    11  *           3:ReDisplay 再显示状态。
    12  *           4:Freeze 冻结状态。
    13  *           
    14  *                  
    15  *    Date: 2017
    16  *    Version: 0.1版本
    17  *    Modify Recoder: 
    18  *    
    19  *   
    20  */
    21 using System.Collections;
    22 using System.Collections.Generic;
    23 using System.ComponentModel.Design;
    24 using UnityEngine;
    25 
    26 namespace SUIFW
    27 {
    28     public class BaseUIForm : MonoBehaviour {
    29         /*字段*/
    30         private UIType _CurrentUIType=new UIType();
    31 
    32         /* 属性*/
    33         //当前UI窗体类型
    34         public UIType CurrentUIType
    35         {
    36             get { return _CurrentUIType; }
    37             set { _CurrentUIType = value; }
    38         }
    39 
    40 
    41         #region  窗体的四种(生命周期)状态
    42 
    43         /// <summary>
    44         /// 显示状态
    45         /// </summary>
    46         public virtual void Display()
    47         {
    48             this.gameObject.SetActive(true);
    49             //设置模态窗体调用(必须是弹出窗体)
    50             if (_CurrentUIType.UIForms_Type==UIFormType.PopUp)
    51             {
    52                 UIMaskMgr.GetInstance().SetMaskWindow(this.gameObject,_CurrentUIType.UIForm_LucencyType);
    53             }
    54         }
    55 
    56         /// <summary>
    57         /// 隐藏状态
    58         /// </summary>
    59         public virtual void Hiding()
    60         {
    61             this.gameObject.SetActive(false);
    62             //取消模态窗体调用
    63             if (_CurrentUIType.UIForms_Type == UIFormType.PopUp)
    64             {
    65                 UIMaskMgr.GetInstance().CancelMaskWindow();
    66             }
    67         }
    68 
    69         /// <summary>
    70         /// 重新显示状态
    71         /// </summary>
    72         public virtual void Redisplay()
    73         {
    74             this.gameObject.SetActive(true);
    75             //设置模态窗体调用(必须是弹出窗体)
    76             if (_CurrentUIType.UIForms_Type == UIFormType.PopUp)
    77             {
    78                 UIMaskMgr.GetInstance().SetMaskWindow(this.gameObject, _CurrentUIType.UIForm_LucencyType);
    79             }
    80         }
    81 
    82         /// <summary>
    83         /// 冻结状态
    84         /// </summary>
    85         public virtual void Freeze()
    86         {
    87             this.gameObject.SetActive(true);
    88         }
    89 
    90 
    91         #endregion
    92 
    93 
    94     }
    95 }
    View Code

     

    以上所讲解的是大体实现思路,还有很多的小细节由于时间关系没有披露,所以特提供下载链接,供感兴趣的开发者研究讨论。欢迎大家提供进一步完善的思路与建议。

     

    本游戏UI框架(截止到以上部分)下载参考链接: 链接:http://pan.baidu.com/s/1nv4plFV 密码:6o0n

     

     

    先讲解到这,我们下次讲解: 游戏UI框架设计(五):配置管理与日志系统

     

  • 相关阅读:
    Microsoft Dynamics CRM 2011 配置好的IFD环境 怎么制作证书?
    Microsoft Dynamics CRM 2011 Plugin中PluginExecutionContext.InputParameters["Target"]中的Target是从哪来的?
    编程写一个方法时,注意方法中传参数的数量最好不要超过5个,超过5个怎么办?可以用struct或class,或一个字典类
    Microsoft Dynamics CRM 2011 常用JS 按F12 改动窗体上数据的方法
    JS 实现轮播图
    JS晃动的花朵
    定时器的应用 盒子的移动
    JavaScript 经典实例
    累加 9*9乘法表 阶乘
    函数方法
  • 原文地址:https://www.cnblogs.com/LiuGuozhu/p/6517791.html
Copyright © 2011-2022 走看看