当前位置:   article > 正文

Unity基于UGUI的UI框架_unityui框架(基于ugui)

unityui框架(基于ugui)

首先

想想我为什么要用UI框架,因为不用UI框架会导致游戏混乱,管理困难?

那么体现在什么方面呢?

一般在设计游戏的时候,会对各个UI面板进行相应的管理,保证同一时间,玩家只对一个UI面板进行操作,保证不会因为玩家乱点,而导致玩家不知道哪个是哪个,或者哪个在哪,还有就是说,让玩家需要哪个UI面板,玩家点击哪个面板的时候再进行相应的实例化加载,不是一股脑的上来全加载出来,等着玩家点按钮调用,那样性能上受不了。

再来想,在UGUI下,UIA和UIB堆在一起谁能显示出来?谁会被覆盖?这个取决于他们在Hierarchy面板的顺序,谁在下面,谁就能被看到,而另一个则会被这一个给覆盖住,而显示不出来。我每实例化出来一个UI面板,都会相应的覆盖住上一个UI面板,然后,当我不用这个UI面板的时候怎么办?我能想到的有三种选择,一个是移动到屏幕显示的外边,让玩家看不到它。二是直接销毁它。三是使用我们的UI框架的栈思想。

但是,第一个会存在什么问题,UI面板的显示完全依赖于Hierarchy面板的顺序,也就是说,每次游戏过程中,这些UI面板谁能遮挡住谁,是根据玩家点击顺序决定的,如果在允许玩家不关上当前窗口的时候进行其他操作的话,玩家夸夸夸的连续点击其他的UI面板,然后再跳出一堆其他的窗口,玩家再想在这些窗口里找到它想要的窗口的话,是非常困难的,因为实例化的顺序不一样,你得按照最上面的那个面板是啥,得一个个对应着关了,才能找到玩家想要的那个面板,再进行操作,当然如果能做好相应的措施还行,不过这么做在UI面板多的情况下,真的会很麻烦。

第二个则不会出现这种问题,但是第二个带来的问题是卡顿,玩过王者荣耀的应该知道,你再大厅界面,点击背包,如果你手机配置很高,则不会那么明显,这里说一般手机,当你刚刚打开游戏,点击背包按钮的时候,你的手机极有可能会顿那么一点几秒,这个过程就是在实例化背包的面板,但是当你关闭了背包之后,再打开,为什么就不卡了?因为背包面板已经被实例化出来了,你刚才将他关闭只是隐藏了它而已。但是如果王者荣耀采用第二种方式呢?当你需要频繁操作某个有很多数据的UI的时候,普通手机的体验会真的很不好。

第三个就牛逼多了。因为加入了类Windows的模态窗口的约束,所以不依赖于Hierarchy面板的顺序,该怎么显示就怎么显示,根据所需实例化所需UI面板,然后需要显示就入栈,需要隐藏就依次出栈,而这些只需要在框架搭好后的几句代码,即可实现,而且只在需要的时候加载对应的UI面板,并存起来,需要的时候再让它显示出来,不浪费性能。

 

UI框架的思想: 

           和栈的思想基本相同,在开发Winform程序和MFC程序的时候,肯定遇到过模态窗口和非模态窗口这个概念,

           定义:对话框分为模态对话框和非模态对话框两种。二者的区别在于当对话框打开时,是否允许用户进行其他对象的操作。

草图构思:

 

也是就说要实现下面这样的功能:

当我点击一个按钮,出现对应模块的时候,我必须关闭这个模块,才能对其他的模块进行操作。

也就是先进后出,我必须倒序的关闭我打开的一切窗口,才能对其他模块进行操作。也就是不断的进行Push操作和Pop操作。

 下面来看下代码实现:

这个是UIManager类 ,整个框架的核心,包含了读取Json数据,到实例化UI面板,再到隐藏UI面板的一切功能。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using LitJson;
  5. using System;
  6. /*
  7. *作者:琦玉老师的二弟子
  8. */
  9. namespace JumpAgent
  10. {
  11. public class UIManager
  12. {
  13. private GameObject ShowCanvas;
  14. /// <summary>
  15. /// 单例模式
  16. /// </summary>
  17. private static UIManager _instance;
  18. /// <summary>
  19. /// 存储所有UI面板的路径的字典
  20. /// </summary>
  21. private Dictionary<UIPanelType, string> panelPathDict;
  22. /// <summary>
  23. /// 保存所有实例化出来的UI面板游戏物体身上的BasePanel组件
  24. /// </summary>
  25. private Dictionary<UIPanelType, BasePanel> panelDict;
  26. /// <summary>
  27. /// UI面板栈,所有入栈的都是显示出来的
  28. /// </summary>
  29. private Stack<BasePanel> panelStack;
  30. /// <summary>
  31. /// 构造方法,读取数据
  32. /// </summary>
  33. private UIManager()
  34. {
  35. ShowCanvas = GameObject.Find("Canvas");
  36. ParseUIPanelTypeJson();
  37. }
  38. /// <summary>
  39. /// 取得单例
  40. /// </summary>
  41. public static UIManager Instance
  42. {
  43. get
  44. {
  45. if (_instance == null)
  46. {
  47. _instance = new UIManager();
  48. }
  49. return _instance;
  50. }
  51. }
  52. /// <summary>
  53. /// 把Json转化成数据
  54. /// </summary>
  55. private void ParseUIPanelTypeJson()
  56. {
  57. //初始化UI面板字典
  58. panelPathDict = new Dictionary<UIPanelType, string>();
  59. //加载Json文件
  60. TextAsset ta = Resources.Load<TextAsset>("UIPanelType");
  61. //取得Json数据转换成的对象,存到集合里面
  62. List<UIPanleInfo> panleInfoList = JsonMapper.ToObject<List<UIPanleInfo>>(ta.text);
  63. //把集合里的对象存到UIPanel的字典里
  64. foreach (UIPanleInfo info in panleInfoList)
  65. {
  66. panelPathDict.Add(info.panelType, info.path);
  67. }
  68. }
  69. /// <summary>
  70. /// 得到一个UI面板,如果该UI面板没有被实例化过,则创建
  71. /// </summary>
  72. /// <param name="panelType"></param>
  73. public BasePanel GetUIPanel(UIPanelType panelType)
  74. {
  75. if (panelDict==null)
  76. {
  77. panelDict = new Dictionary<UIPanelType, BasePanel>();
  78. }
  79. //BasePanel basePanel;
  80. //panelDict.TryGetValue(panelType, out basePanel);
  81. //扩展方法
  82. BasePanel basePanel = panelDict.TryGet(panelType);
  83. if (basePanel==null)
  84. {
  85. string path;
  86. panelPathDict.TryGetValue(panelType, out path);
  87. GameObject InsPanel=(GameObject)GameObject.Instantiate(Resources.Load(path));
  88. InsPanel.transform.SetParent(ShowCanvas.gameObject.transform,false);
  89. panelDict.Add(panelType, InsPanel.GetComponent<BasePanel>());
  90. return InsPanel.GetComponent<BasePanel>();
  91. }
  92. else
  93. {
  94. return basePanel;
  95. }
  96. }
  97. /// <summary>
  98. /// 入栈,把某个页面显示在界面上
  99. /// </summary>
  100. public void PushPanel(UIPanelType panelType)
  101. {
  102. if (panelStack==null)
  103. {
  104. panelStack = new Stack<BasePanel>();
  105. }
  106. if (panelStack.Count>0)
  107. {
  108. BasePanel topPanel = panelStack.Peek();
  109. topPanel.OnPause();
  110. }
  111. BasePanel panel = GetUIPanel(panelType);
  112. panel.OnEnter();
  113. panelStack.Push(panel);
  114. }
  115. /// <summary>
  116. /// 出栈,把某个页面从界面上移除
  117. /// </summary>
  118. public void PopPanel()
  119. {
  120. if (panelStack == null)
  121. {
  122. panelStack = new Stack<BasePanel>();
  123. }
  124. if (panelStack.Count==0)
  125. {
  126. return;
  127. }
  128. //关闭栈顶页面的显示
  129. BasePanel topPanel = panelStack.Pop();
  130. topPanel.OnExit();
  131. if (panelStack.Count != 0)
  132. {
  133. BasePanel nextPanel = panelStack.Peek();
  134. nextPanel.OnResume();
  135. }
  136. }
  137. /// <summary>
  138. /// 测试方法
  139. /// </summary>
  140. public void Test()
  141. {
  142. foreach (var item in panelPathDict)
  143. {
  144. Debug.Log("Panel类型为:" + item.Key + "__路径为:" + item.Value);
  145. }
  146. }
  147. }//类
  148. }//命名空间

再然后是所有BasePanel,即所有UI面板的基类:继承这个基类的子类UI面板需要重写里面的这四个虚方法,以供我们的UIManager调用。

  1. using System.Collections;
  2. using System.Collections.Generic;
  3. using UnityEngine;
  4. using DG.Tweening;
  5. /*
  6. 作者:琦玉老师的二弟子
  7. */
  8. namespace JumpAgent{
  9. public class BasePanel : MonoBehaviour
  10. {
  11. /// <summary>
  12. /// 显示界面
  13. /// </summary>
  14. public virtual void OnEnter()
  15. {
  16. }
  17. /// <summary>
  18. /// 界面暂停
  19. /// </summary>
  20. public virtual void OnPause()
  21. {
  22. }
  23. /// <summary>
  24. /// 界面继续
  25. /// </summary>
  26. public virtual void OnResume()
  27. {
  28. }
  29. /// <summary>
  30. /// 界面推出
  31. /// </summary>
  32. public virtual void OnExit()
  33. {
  34. }
  35. }//类
  36. }//命名空间

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/运维做开发/article/detail/761567
推荐阅读
相关标签
  

闽ICP备14008679号