UI框架(UGUI)
发表于2018-03-21
本篇文章是通过Demo来和大家介绍UI框架,希望这样可以更方便大家学习掌握,主要也是考虑到了有些细节在文章中很难都全部介绍到。
工具:VS2010、Unity5.2.3f
先介绍整个Demo的主面板
其中任务、技能、符文等等都是按钮,点击按钮会生成相应面板
【Protobuf的生成与解析】
要使得框架的可扩展性与自适应性,我把各个面板的名字与路径配置到protobuf文件
在VS中我们把代码编写完成后生成protobuf文件,在Unity中解析。
如何生成与解析可以参考:
【UIManager】
在Unity工程中,使用UIManager这个类对整个UI框架进行管理
UIManager.cs
using UnityEngine; using System.Collections; using UIFrameworkForProtobuf; using System.Collections.Generic; public class UIManager { private Dictionary<UIPanelTypeEnum, string> dicPanelPath;//存储面板路径 private Dictionary<UIPanelTypeEnum, BaseManager> dicPanelBase;//存储面板BaseManager组件 private Stack<BaseManager> panelStack; //单例模式 private static UIManager manager; public static UIManager GetInstance { get { if (manager == null) { manager = new UIManager(); } return manager; } } private UIManager() { Dederializer(); } private Transform canvasTransform; private Transform CanvasTransform { get { if (canvasTransform == null) { canvasTransform = GameObject.Find("Canvas").transform; } return canvasTransform; } } <span style="white-space:pre;"> </span>
<span style="white-space:pre;"> </span>//面板入栈 public void PushPanel(UIPanelTypeEnum panelType) { if (panelStack == null) { panelStack = new Stack<BaseManager>(); } //判断栈里面是否有页面,如果有,将栈中top对象取出 if (panelStack.Count > 0) { BaseManager top = panelStack.Peek(); top.OnPause(); } BaseManager bm = GetPanel(panelType); panelStack.Push(bm); bm.OnEnter(); } <span style="white-space:pre;"> </span>
<span style="white-space:pre;"> </span>//面板出栈 public void PopPanel() { if (panelStack == null) { panelStack = new Stack<BaseManager>(); } if (panelStack.Count <= 0) { return; } //关闭栈顶的页面显示 BaseManager bm = panelStack.Pop(); bm.OnExit(); if (panelStack.Count <= 0) { return; } BaseManager top = panelStack.Peek(); top.OnResume(); } private BaseManager GetPanel(UIPanelTypeEnum panelType) { if (dicPanelBase == null) { dicPanelBase = new Dictionary<UIPanelTypeEnum, BaseManager>(); } BaseManager bm; dicPanelBase.TryGetValue(panelType,out bm); if (bm == null) { string panelPath; dicPanelPath.TryGetValue(panelType, out panelPath); GameObject objPanel = GameObject.Instantiate(Resources.Load(panelPath)) as GameObject; objPanel.transform.SetParent(CanvasTransform, false);//参数二:是否保留世界坐标信息,由于要将对象存放在Canvase下,所以为false dicPanelBase.Add(panelType, objPanel.GetComponent<BaseManager>()); return objPanel.GetComponent<BaseManager>(); } else { return bm; } } //将protobuf文件反序列化为对象 private void Dederializer() { dicPanelPath = new Dictionary<UIPanelTypeEnum, string>(); UIPanelTypeList panelTypes = ProtobufHelper.DederializerFromFile<UIPanelTypeList>(Application.streamingAssetsPath + "/UIPanelType.bin"); foreach (UIPanelType type in panelTypes.uiPanelTypes) { UIPanelTypeEnum enumType = (UIPanelTypeEnum)System.Enum.Parse(typeof(UIPanelTypeEnum), type.panelName); dicPanelPath.Add(enumType, type.panelPath); Debug.Log(type.panelName); Debug.Log(type.panelPath); } } }
【面板状态组件】
我们为每个面板添加一个C#脚本组件,分别命名为TaskPanel、SkillPanel……
他们分别继承自BaseManager类
BaseManager.cs
using UnityEngine; using System.Collections; public class BaseManager :MonoBehaviour { /// <summary> /// 界面显示 /// </summary> public virtual void OnEnter() { } /// <summary> /// 界面暂停 /// </summary> public virtual void OnPause() { } /// <summary> /// 界面继续 /// </summary> public virtual void OnResume() { } /// <summary> /// 界面不显示,退出这个界面,界面被关闭 /// </summary> public virtual void OnExit() { } }
这里介绍主面板的MainPanel组件
MainPanel.cs
using UnityEngine; using System.Collections; public class MainPanel : BaseManager { private CanvasGroup canvasGroup; void Start() { canvasGroup = GetComponent<CanvasGroup>(); } public override void OnPause() { canvasGroup.blocksRaycasts = false;//当弹出新的面板的时候,让主菜单面板 不再和鼠标交互 } public override void OnResume() { canvasGroup.blocksRaycasts = true; } public void OnPushPanel(string panelTypeString) { UIPanelTypeEnum panelType = (UIPanelTypeEnum)System.Enum.Parse(typeof(UIPanelTypeEnum), panelTypeString); UIManager.GetInstance.PushPanel(panelType); } }
主面板的各个按钮中,将按钮点击事件注册到OnPushPanel函数中,并传入一个面板名
【检测】
将主面板添加到游戏对象上
ManagerRoot.cs
using UnityEngine; using System.Collections; public class ManagerRoot : MonoBehaviour { // Use this for initialization void Start () { UIManager.GetInstance.PushPanel(UIPanelTypeEnum.Main); } }
整个游戏的工程源码下载链接:打开链接
来自:http://blog.csdn.net/qq_33747722/article/details/66967632