游戏UI框架设计(二) : 最简版本设计

最简版本设计

--最简版本设计

  为降低难度决定先讲解一个最简版本,阐述UI框架的核心设计理念。这里先定义三个核心功能:

1:UI窗体的自动加载功能。

2:缓存UI窗体。

3:窗体生命周期(状态)管理。

UI框架设计主要目的,就是尽可能的完成一些与具体游戏功能逻辑无关的一些底层事务性的功能实现。这些功能最好是自动或者是半自动的实现,无须客户程序(调用框架的程序)过多处理与关心。

  对于以上功能,笔者定义了UI框架的相关四个核心类:

  • BaseUIForms    基础UI窗体脚本(父类,其他窗体都继承此脚本)
  • UIManger.cs    UI窗体管理器脚本(框架核心脚本)
  • UIType      窗体类型 (引用窗体的重要属性[枚举类型])
  • SysDefine       系统定义类(包含框架中使用到的枚举类型、委托事件、系统常量、接口等)

  在SysDefine 文件中,定义本框架三个核心枚举类型:

1     //UI窗体(位置)类型

2     public enum UIFormType

3     {

4         //普通窗体

5         Normal,

6         //固定窗体

7         Fixed,

8         //弹出窗体

9         PopUp

10     }

11

12     //UI窗体的显示类型

13     public enum UIFormShowMode

14     {

15         //普通

16         Normal,

17         //反向切换

18         ReverseChange,

19         //隐藏其他

20         HideOther

21     }

22

23     //UI窗体透明度类型

24     public enum UIFormLucenyType

25     {

26         //完全透明,不能穿透

27         Lucency,

28         //半透明,不能穿透

29         Translucence,

30         //低透明度,不能穿透

31         ImPenetrable,

32         //可以穿透

33         Pentrate

34     }

上述三个核心枚举类型,解释如下:

  1. UIFormType 枚举类型,表示Unity层级视图中挂载不同类型窗体的空节点。这里Fixed 表示固定窗体,表示可以挂载"非全屏非弹出窗体",例如RPG游戏项目中的“英雄信息”窗体等。
  2. UIFormShowMode 枚举,表示窗体不同的显示方式。Normal 类型表示窗体与其他窗体可以并列显示; HideOther类型表示窗体显示的时候,需要隐藏所有其他窗体; ReverseChange 窗体主要应用与"弹出窗体",维护多个弹出窗体的层级关系。
  3. UIFormLucenyType 枚举,是定义弹出“模态窗体”不同透明度的类型。

上图是我们定义的UGUI 中的“根窗体”预设 "Canvas",在Untiy的层级视图中,可以看到我们定义了若干空节点,用于不同类型的UI窗体加载到不同的“根窗体”预设中,实现不同显示效果。
  定义 UIType 类,主要是引用定义的三个核心枚举,方便使用 。代码如下:

1     /// <summary>

2     /// UI(窗体)类型

3     /// </summary>

4     internal class UIType

5     {

6         //是否需要清空“反向切换”

7         public boolIsClearReverseChange = false;

8         //UI窗体类型

9         public UIFormsType UIForms_Type = UIFormsType.Normal;

10         //UI窗体显示类型

11         publicUIFormsShowMode UIForms_ShowMode =UIFormsShowMode.Normal;

12         //UI窗体透明度类型

13         publicUIFormsLucencyType UIForms_LucencyType =UIFormsLucencyType.Lucency;

14     }

定义基础UI窗体 BaseUIForms 脚本,代码如下:

1     public class BaseUIForms : MonoBehaviour

2     {

3         /*  字段 */

4         //当前(基类)窗口的类型

5         privateUIType _CurrentUIType=new UIType();

6

7         /*  属性 */

8         /// <summary>

9         ///属性_当前UI窗体类型

10         /// </summary>

11         internal UIType CurrentUIType

12         {

13             set

14             {

15                 _CurrentUIType =value;

16             }

17

18             get

19             {

20                 return _CurrentUIType;

21             }

22         }

23

24         //页面显示

25         publicvirtual void Display()

26         {

27             this.gameObject.SetActive(true);

28         }

29

30         //页面隐藏(不在“栈”集合中)

31         publicvirtual void Hiding()

32         {

33             this.gameObject.SetActive(false);

34         }

35         //页面重新显示

36         publicvirtual void Redisplay()

37         {

38             this.gameObject.SetActive(true);

39         }

40         //页面冻结(还在“栈”集合中)

41         publicvirtual void Freeze()

42         {

43             this.gameObject.SetActive(true);

44         }

45

46     }//Class_end

上述代码中,主要定义了UI窗体基类的四个重要虚方法,分别对应窗体的打开显示、隐藏、重新显示、窗体冻结(即:窗体显示在其他窗体下面)。方便窗体在不同状态下,针对不同的行为进一步做处理操作。例如,当窗体为“隐藏”与“冻结”状态时,如果此窗体有针对远程服务的网络连接(Socket套接字)时,则需要关闭网络连接,以节省网络资源。

  定义“UI管理器”(UIManager.cs) 脚本,这是UI框架中的核心脚本,主要负责UI窗体的加载、缓存、以及对于“UI窗体基类”的各种生命周期的操作(显示、隐藏、重新显示、冻结)。

1 public class UIManager : MonoBehaviour {

2         /* 字段 */

3         private staticUIManager _Instance = null;

4         //UI窗体预设路径(参数1:窗体预设名称,2:表示窗体预设路径)

5         private Dictionary<string,string>_DicFormsPaths;

6         //缓存所有UI窗体

7         private Dictionary<string,BaseUIForm> _DicALLUIForms;

8         //当前显示的UI窗体

9         private Dictionary<string,BaseUIForm> _DicCurrentShowUIForms;

10         //UI根节点

11         private Transform _TraCanvasTransfrom = null;

12         //全屏幕显示的节点

13         private Transform _TraNormal = null;

14         //固定显示的节点

15         private Transform _TraFixed = null;

16         //弹出节点

17         private Transform _TraPopUp = null;

18         //UI管理脚本的节点

19         private Transform _TraUIScripts = null;

20

21

22         /// <summary>

23         ///得到实例

24         /// </summary>

25         /// <returns></returns>

26         public static UIManager GetInstance()

27         {

28             if (_Instance==null)

29             {

30                _Instance = new GameObject("_UIManager").AddComponent<UIManager>();

31             }

32             return _Instance;

33         }

34

35         //初始化核心数据,加载“UI窗体路径”到集合中。

36         public void Awake()

37         {

38             //字段初始化

39            _DicALLUIForms=new Dictionary<string, BaseUIForm>();

40            _DicCurrentShowUIForms=newDictionary<string, BaseUIForm>();

41            _DicFormsPaths=new Dictionary<string, string>();

42             //初始化加载(根UI窗体)Canvas预设

43             InitRootCanvasLoading();

44             //得到UI根节点、全屏节点、固定节点、弹出节点

45            _TraCanvasTransfrom =GameObject.FindGameObjectWithTag(SysDefine.SYS_TAG_CANVAS).transform;

46            _TraNormal = _TraCanvasTransfrom.Find("Normal");

47            _TraFixed = _TraCanvasTransfrom.Find("Fixed");

48            _TraPopUp = _TraCanvasTransfrom.Find("PopUp");

49            _TraUIScripts = _TraCanvasTransfrom.Find("_ScriptMgr");

50             //把本脚本作为“根UI窗体”的子节点。

51             this.gameObject.transform.SetParent(_TraUIScripts, false);

52             //"根UI窗体"在场景转换的时候,不允许销毁

53             DontDestroyOnLoad(_TraCanvasTransfrom);

54             //初始化“UI窗体预设”路径数据

55             //先写简单的,后面我们使用Json做配置文件,来完善。

56             if(_DicFormsPaths!=null)

57             {

58                _DicFormsPaths.Add("LogonUIForm",@"UIPrefabs\LogonUIForm");

59             }

60         }

61

62         /// <summary>

63         ///显示(打开)UI窗体

64         ///功能:

65         /// 1: 根据UI窗体的名称,加载到“所有UI窗体”缓存集合中

66         /// 2: 根据不同的UI窗体的“显示模式”,分别作不同的加载处理

67         /// </summary>

68         /// <paramname="uiFormName">UI窗体预设的名称</param>

69         public voidShowUIForms(stringuiFormName)

70         {

71             BaseUIFormbaseUIForms=null;                    //UI窗体基类

72

73             //参数的检查

74             if (string.IsNullOrEmpty(uiFormName))return;

75             //根据UI窗体的名称,加载到“所有UI窗体”缓存集合中

76            baseUIForms = LoadFormsToAllUIFormsCatch(uiFormName);

77             if (baseUIForms == null)return;

78             //根据不同的UI窗体的显示模式,分别作不同的加载处理

79             switch(baseUIForms.CurrentUIType.UIForms_ShowMode)

80             {

81                 caseUIFormShowMode.Normal:                 //“普通显示”窗口模式

82                    //把当前窗体加载到“当前窗体”集合中。

83                     LoadUIToCurrentCache(uiFormName);

84                    break;

85                 case UIFormShowMode.ReverseChange:          //需要“反向切换”窗口模式

86                    //更靠后课程进行讲解。

87                    break;

88                 case UIFormShowMode.HideOther:              //“隐藏其他”窗口模式

89                    //更靠后课程进行讲解。

90                    break;

91                 default:

92                    break;

93             }

94         }

95

96         #region 私有方法

97         //初始化加载(根UI窗体)Canvas预设

98         private void InitRootCanvasLoading()

99         {

100             ResourcesMgr.GetInstance().LoadAsset(SysDefine.SYS_PATH_CANVAS,false);

101         }

102

103         /// <summary>

104         ///根据UI窗体的名称,加载到“所有UI窗体”缓存集合中

105         ///功能: 检查“所有UI窗体”集合中,是否已经加载过,否则才加载。

106         /// </summary>

107         /// <param name="uiFormsName">UI窗体(预设)的名称</param>

108         /// <returns></returns>

109         privateBaseUIForm LoadFormsToAllUIFormsCatch(string uiFormsName)

110         {

111             BaseUIForm baseUIResult = null;                //加载的返回UI窗体基类

112

113            _DicALLUIForms.TryGetValue(uiFormsName, out baseUIResult);

114             if(baseUIResult==null)

115             {

116                 //加载指定名称的“UI窗体”

117                 baseUIResult = LoadUIForm(uiFormsName);

118             }

119

120             return baseUIResult;

121         }

122

123         /// <summary>

124         ///加载指定名称的“UI窗体”

125         ///功能:

126         ///    1:根据“UI窗体名称”,加载预设克隆体。

127         ///    2:根据不同预设克隆体中带的脚本中不同的“位置信息”,加载到“根窗体”下不同的节点。

128         ///    3:隐藏刚创建的UI克隆体。

129         ///    4:把克隆体,加入到“所有UI窗体”(缓存)集合中。

130         ///

131         /// </summary>

132         /// <param name="uiFormName">UI窗体名称</param>

133         privateBaseUIForm LoadUIForm(string uiFormName)

134         {

135             stringstrUIFormPaths = null;                   //UI窗体路径

136             GameObject goCloneUIPrefabs = null;            //创建的UI克隆体预设

137             BaseUIForm baseUiForm=null;                     //窗体基类

138

139

140             //根据UI窗体名称,得到对应的加载路径

141             _DicFormsPaths.TryGetValue(uiFormName,out strUIFormPaths);

142             //根据“UI窗体名称”,加载“预设克隆体”

143             if(!string.IsNullOrEmpty(strUIFormPaths))

144             {

145                 goCloneUIPrefabs =ResourcesMgr.GetInstance().LoadAsset(strUIFormPaths, false);

146             }

147             //设置“UI克隆体”的父节点(根据克隆体中带的脚本中不同的“位置信息”)

148             if(_TraCanvasTransfrom != null &&goCloneUIPrefabs != null)

149             {

150                 baseUiForm =goCloneUIPrefabs.GetComponent<BaseUIForm>();

151                 if(baseUiForm == null)

152                 {

153                     Debug.Log("baseUiForm==null! ,请先确认窗体预设对象上是否加载了baseUIForm的子类脚本! 参数 uiFormName=" + uiFormName);

154                     returnnull;

155                 }

156                 switch (baseUiForm.CurrentUIType.UIForms_Type)

157                 {

158                     caseUIFormType.Normal: //普通窗体节点

159                        goCloneUIPrefabs.transform.SetParent(_TraNormal, false);

160                         break;

161                     caseUIFormType.Fixed: //固定窗体节点

162                        goCloneUIPrefabs.transform.SetParent(_TraFixed, false);

163                         break;

164                     caseUIFormType.PopUp: //弹出窗体节点

165                         goCloneUIPrefabs.transform.SetParent(_TraPopUp,false);

166                         break;

167                     default:

168                         break;

169                 }

170

171                 //设置隐藏

172                 goCloneUIPrefabs.SetActive(false);

173                 //把克隆体,加入到“所有UI窗体”(缓存)集合中。

174                 _DicALLUIForms.Add(uiFormName,baseUiForm);

175                 return baseUiForm;

176             }

177             else

178             {

179                 Debug.Log("_TraCanvasTransfrom==nullOr goCloneUIPrefabs==null!! ,Plese Check!, 参数uiFormName="+uiFormName);

180             }

181

182             Debug.Log("出现不可以预估的错误,请检查,参数 uiFormName="+uiFormName);

183             returnnull;

184         }//Mehtod_end

185

186         /// <summary>

187         ///把当前窗体加载到“当前窗体”集合中

188         /// </summary>

189         /// <param name="uiFormName">窗体预设的名称</param>

190         privatevoid LoadUIToCurrentCache(string uiFormName)

191         {

192             BaseUIForm baseUiForm;                          //UI窗体基类

193             BaseUIFormbaseUIFormFromAllCache;              //从“所有窗体集合”中得到的窗体

194

195             //如果“正在显示”的集合中,存在整个UI窗体,则直接返回

196            _DicCurrentShowUIForms.TryGetValue(uiFormName, out baseUiForm);

197             if(baseUiForm != null) return;

198             //把当前窗体,加载到“正在显示”集合中

199            _DicALLUIForms.TryGetValue(uiFormName, out baseUIFormFromAllCache);

200             if(baseUIFormFromAllCache!=null)

201             {

202                 _DicCurrentShowUIForms.Add(uiFormName,baseUIFormFromAllCache);

203                baseUIFormFromAllCache.Display();           //显示当前窗体

204             }

205         }

206

207         #endregion

208

209     }//class_end

UI管理器脚本解释如下:

一:上述代码中重要字段的解释如下:
   1:  “_DicFormsPaths” 表示“UI窗体预设路径”集合,负责缓存所有UI窗体预设的名称与对应资源路径的关系。
   2: “ _DicALLUIForms” 表示“所有UI窗体”集合,负责缓存已经加载过的所有UI窗体名称以及与之对应的UI窗体。
   3: “_DicCurrentShowUIForms”表示“当前正在显示”集合,负责控制正在显示UI窗体的内部逻辑。
   4: UI管理器脚本中的“_TraCanvasTransfrom”、“_TraNormal”、“_TraFixed”、“_TraPopUp”、“_TraUIScripts”,分别表示Unity层级视图中的根结点、普通节点、固定节点、弹出节点、管理脚本节点,这些节点是加载UI窗体的不同类型的父节点,用于各种UI窗体的管理工作。
二:上述代码中重要方法的解释如下:
  1: ShowUIForms()  是外部程序调用本框架的对外公共方法,负责加载、缓存、打开与显示制定窗体名称的UI窗体预设。
  2: LoadFormsToAllUIFormsCatch() 是根据UI窗体的名称,加载到“所有UI窗体”缓存集合中。
  3: LoadUIToCurrentCache() 是把当前窗体加载到“当前窗体”集合中。
  上述(UI框架)脚本编写完毕,测试成功后效果如下图:

为广大读者进一步了解与熟悉本框架,特提供下载链接:http://pan.baidu.com/s/1skN2Njn 密码:2ey6

本篇就先写到这,下篇 "游戏UI框架设计(3)_窗体的层级管理" 继续。

时间: 2025-01-06 06:48:09

游戏UI框架设计(二) : 最简版本设计的相关文章

游戏UI框架设计(五): 配置管理与应用

游戏UI框架设计(五) --配置管理与应用 在开发企业级游戏/VR/AR产品时候,我们总是希望可以总结出一些通用的技术体系,框架结构等,为简化我们的开发起到"四两拨千金"的作用.所谓"配置管理"是指一个游戏项目(软件项目),很多需要经常变化的需求或者数据,最好以配置文件的形式存在,从而代替"硬编码"方式.      这里笔者就对游戏产品中大量应用到动态加载的情形,开发出一套通用的配置管理(脚本)工具.该工具可以很方便的对于具备"键值对&

游戏UI框架设计(五): 配置管理与应用

游戏UI框架设计(五) --配置管理与应用 在开发企业级游戏/VR/AR产品时候,我们总是希望可以总结出一些通用的技术体系,框架结构等,为简化我们的开发起到"四两拨千金"的作用.所谓"配置管理"是指一个游戏项目(软件项目),很多需要经常变化的需求或者数据,最好以配置文件的形式存在,从而代替"硬编码"方式. 这里笔者就对游戏产品中大量应用到动态加载的情形,开发出一套通用的配置管理(脚本)工具.该工具可以很方便的对于具备"键值对"

游戏UI框架设计(四) : 模态窗体管理

游戏UI框架设计(四) --模态窗体管理 我们在开发UI窗体时,对于"弹出窗体"往往因为需要玩家优先处理弹出小窗体,则要求玩家不能(无法)点击"父窗体",这种窗体就是典型的"模态窗体".在此笔者设计了四种模式类型:完全透明.半透明.低透明度.透明且可以穿透. (透明不能穿透) (半透明不能穿透) (低透明度,不能穿透) 对于"模态窗体"的基本实现原理是: 在弹出窗体的后面增加一层"UI遮罩窗体",当需要弹出

游戏UI框架设计(7): 资源国际化技术

游戏UI框架设计(7) --资源国际化技术 说起"资源国际化"技术,个人认为可以追述到微软Window2000 PC操作系统的发布,在这之前windows98操作系统的开发都是先由美国总部出一个英文版本,然后在发布windows 版本之后的大约一年后,全世界其他语言版本的操作系统才能面世. 在这一年中,就是微软驻各个国家分公司的多语言版本的翻译工作,需要从操作系统的核心到外围软件,全部翻译为所在国家语言,不留死角.       这种情况对于微软来说需要为多语言版本付出额外非常大的经济负

游戏UI框架设计(三) : 窗体的层级管理

游戏UI框架设计(三) ---窗体的层级管理 UI框架中UI窗体的"层级管理",最核心的问题是如何进行窗体的显示管理.窗体(预设)的显示我们前面定义了三种类型: 普通.隐藏其他.反向切换.代码如下: "普通显示"模式允许多个窗体同时显示,这种类型应用最多.例如RPG中的主城界面(见下图). "隐藏其他界面" 模式一般应用于全局性的窗体.我们在开发此类窗体时,为了减少UI渲染压力.提高Unity渲染效率,则设置被覆盖的窗体为"不可见&qu

H+后台主题UI框架---整理(二)

本篇文章是针对H+后台主题UI框架的整理的第二部分.主要只有一个point.如下: 其代码如下: <div class="ibox float-e-margins"> <div class="ibox-title"> <h5>数据报告</h5> <span class="label label-primary">K+</span> <div class="ib

游戏UI界面框架设计系列视频课程

课程目标使得进入游戏(VR/AR)公司的开发人员,快速掌握基于Unity引擎的UI界面框架设计理念.原理.功能设计与全套技术实现.通过学习可以快速胜任复杂UI开发工作,成为公司核心主力开发人员,为进一步成为"主程",打下坚实的基础!适用人群初中级开发人员或者系统学习过"刘老师讲Unity"就业系列课程的学员.课程简介本课程总体分为七大部分: 一: UI框架设计理念       整体简单介绍即将带领大家开发的UI框架的功能设计.核心类设计等,让大家有一个整体.大概的了

《开源框架那些事儿22》:UI框架设计实战

UI是User Interface的缩写,通常被认为是MVC中View的部分,作用是提供跟人机交互的可视化操作界面.MVC中Model提供内容给UI进行渲染,用户通过UI框架产生响应,一般而言会由控制层调用业务逻辑进行处理,并把处理结果以Model方式返回View,再次渲染.UI框架的大致过程就是如此,按实现方式可以分为RIA和瘦客户端方式,目前基于B/S的瘦客户端方式比较流行.UI框架套路上很简单,但是想要做好可就不容易了.目前基于MVC的框架灿若繁星,不客气的说是个软件公司就有自己的技术框架

软件UI设计二

接上篇博客 UI设计一 二.如何设计UI--大道至简 如何设计UI,四个字足矣:大道至简. 2.1 原则 1.搜索--模糊到极致 这不是我说的,是老师说的,是百度说的,是谷歌说的,看证据就在这里: 一个搜索框,解决所有问题.看看我们是怎么设计的:  一个查询页面有两个以上的查询条件,让用户去填写,美其名曰是"精确查询"其实,是我们设计人员错了,这样方便的不是用户,而是我们开发人员,方便了我们编程,并没有方便用户,用户要是知道那么精确,就不必使用系统了,就是用户不清楚,我们要做到,在用户