您的位置:首页 > 产品设计 > UI/UE

游戏UI框架设计(四)

2019-05-17 16:10 169 查看

转自:https://www.cnblogs.com/LiuGuozhu/p/6517791.html

游戏UI框架设计(四)

--模态窗体管理

 

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

     

  (透明不能穿透)

     

    (半透明不能穿透)

     

     (低透明度,不能穿透)

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

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

    

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

   

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

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

 

[code]  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 }

 

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

[code] 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 }

 

 

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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: