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

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

2017-02-21 10:12 393 查看
最简版本设计--最简版本设计
  为降低难度决定先讲解一个最简版本,阐述UI框架的核心设计理念。这里先定义三个核心功能: 1:UI窗体的自动加载功能。 2:缓存UI窗体。 3:窗体生命周期(状态)管理。 UI框架设计主要目的,就是尽可能的完成一些与具体游戏功能逻辑无关的一些底层事务性的功能实现。这些功能最好是自动或者是半自动的实现,无须客户程序(调用框架的程序)过多处理与关心。
  对于以上功能,笔者定义了UI框架的相关四个核心类:
BaseUIForms 基础UI窗体脚本(父类,其他窗体都继承此脚本)

UIManger.cs UI窗体管理器脚本(框架核心脚本)

UIType 窗体类型 (引用窗体的重要属性[枚举类型])

SysDefine 系统定义类(包含框架中使用到的枚举类型、委托事件、系统常量、接口等)

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

1 //UI窗体(位置)类型2 public enum UIFormType3 {4 //普通窗体5 Normal, 6 //固定窗体 7 Fixed,8 //弹出窗体9 PopUp10 }11 12 //UI窗体的显示类型13 public enum UIFormShowMode14 {15 //普通16 Normal,17 //反向切换18 ReverseChange,19 //隐藏其他20 HideOther21 }2223 //UI窗体透明度类型24 public enum UIFormLucenyType25 {26 //完全透明,不能穿透27 Lucency,28 //半透明,不能穿透29 Translucence,30 //低透明度,不能穿透31 ImPenetrable,32 //可以穿透33 Pentrate 34 }

上述三个核心枚举类型,解释如下: UIFormType 枚举类型,表示Unity层级视图中挂载不同类型窗体的空节点。这里Fixed 表示固定窗体,表示可以挂载"非全屏非弹出窗体",例如RPG游戏项目中的“英雄信息”窗体等。

UIFormShowMode 枚举,表示窗体不同的显示方式。Normal 类型表示窗体与其他窗体可以并列显示; HideOther类型表示窗体显示的时候,需要隐藏所有其他窗体; ReverseChange 窗体主要应用与"弹出窗体",维护多个弹出窗体的层级关系。

UIFormLucenyType 枚举,是定义弹出“模态窗体”不同透明度的类型。






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

1 /// <summary>2 /// UI(窗体)类型3 /// </summary>4 internal class UIType5 {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 : MonoBehaviour2 {3 /* 字段 */4 //当前(基类)窗口的类型5 privateUIType _CurrentUIType=new UIType();67 /* 属性 */8 /// <summary>9 ///属性_当前UI窗体类型10 /// </summary>11 internal UIType CurrentUIType12 {13 set14 {15 _CurrentUIType =value;16 }1718 get19 {20 return _CurrentUIType;21 }22 }2324 //页面显示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 } 4546 }//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;202122 /// <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 }3435 //初始化核心数据,加载“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 }6162 /// <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窗体基类7273 //参数的检查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 }9596 #region 私有方法97 //初始化加载(根UI窗体)Canvas预设98 private void InitRootCanvasLoading()99 {100 ResourcesMgr.GetInstance().LoadAsset(SysDefine.SYS_PATH_CANVAS,false);101 }102103 /// <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窗体基类112113 _DicALLUIForms.TryGetValue(uiFormsName, out baseUIResult);114 if(baseUIResult==null)115 {116 //加载指定名称的“UI窗体”117 baseUIResult = LoadUIForm(uiFormsName);118 }119120 return baseUIResult;121 }122123 /// <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; //窗体基类138139140 //根据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 }170171 //设置隐藏172 goCloneUIPrefabs.SetActive(false);173 //把克隆体,加入到“所有UI窗体”(缓存)集合中。174 _DicALLUIForms.Add(uiFormName,baseUiForm);175 return baseUiForm;176 }177 else178 {179 Debug.Log("_TraCanvasTransfrom==nullOr goCloneUIPrefabs==null!! ,Plese Check!, 参数uiFormName="+uiFormName); 180 }181182 Debug.Log("出现不可以预估的错误,请检查,参数 uiFormName="+uiFormName);183 returnnull;184 }//Mehtod_end185186 /// <summary>187 ///把当前窗体加载到“当前窗体”集合中188 /// </summary>189 /// <param name="uiFormName">窗体预设的名称</param>190 privatevoid LoadUIToCurrentCache(string uiFormName)191 {192 BaseUIForm baseUiForm; //UI窗体基类193 BaseUIFormbaseUIFormFromAllCache; //从“所有窗体集合”中得到的窗体194195 //如果“正在显示”的集合中,存在整个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 }206207 #endregion208209 }//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)_窗体的层级管理" 继续。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  游戏 框架 UnityUI