之前学了刘国柱老师的UI框架加上我自己的理解做了一个UI框架正好可以使用
http://www.cnblogs.com/LiuGuozhu/ 受益颇深
基本UI框架的类图就是这样了
大体是根据MVC加上我的魔改而成的框架,至少我自己暂时觉得还是思路挺清晰的
Panel的切换是使用的Canvas Group的更改透明度,在加上使用
此方法来更改显示顺序和显隐的
其中的界面反向切换是使用的栈后入先出的特性
反向切换是指一个窗口弹出小窗口后,父窗口的Raycast需要取消,下面贴上核心代码
using System.Collections; using System; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class UIManager :MonoBehaviour { /// <summary> /// 单例模式: /// 1.定义一个静态的对象 在外界访问 内部构造 /// 2.构造方法私有化 /// </summary> #region 单例模式 private static UIManager _instance; public static UIManager Instance { get { if (_instance == null) { UIManager[] instances = FindObjectsOfType<UIManager>(); if (instances != null) { _instance = instances[0]; for (var i = 1; i < instances.Length; i++) { Destroy(instances[i].gameObject); } } } return _instance; } } #endregion private Transform _canvas; public Transform Canvas { get { if (_canvas == null) _canvas = GameObject.Find("Canvas").transform; return _canvas; } } //存储所有面板prefab的地址 private Dictionary<UIPanelType, string> _DicPanelPath; //存储所有实例化的面板身上的BasePanel组件 private Dictionary<UIPanelType, BasePanel> _DicPanel; //存储所有显示的面板上的BasePanel组件 private Dictionary<UIPanelType, BasePanel> _DicShowPanel; //表示显示面板的栈 private Stack<BasePanel> _StackPanel; //全屏显示的节点 private Transform _TraFullScreen = null; //固定显示的节点 private Transform _TraFixed = null; //弹出节点 private Transform _TraPopUp = null; ////脚本节点 //private Transform _TraScript = null; private void Awake() { ParseUIPanelPathJson(); _StackPanel = new Stack<BasePanel>(); _DicPanel = new Dictionary<UIPanelType, BasePanel>(); _DicShowPanel = new Dictionary<UIPanelType, BasePanel>(); _TraFullScreen = Canvas.Find("FullScreen"); _TraFixed = Canvas.Find("Fixed"); _TraPopUp = Canvas.Find("PopUp"); DontDestroyOnLoad(Canvas.gameObject); //_TraScript = Canvas.Find("Script"); } /// <summary> /// 把类型为反向切换的窗体入栈 /// </summary> /// <param name="type"></param> private void PushPanel(UIPanelType type) { BasePanel basePanel = GetPanel(type); if (_StackPanel.Count >= 1) { BasePanel topPanel = _StackPanel.Peek(); topPanel.OnPause(); } _StackPanel.Push(basePanel); basePanel.OnEnter(); } /// <summary> /// 把类型为反向切换的窗体出栈 /// </summary> /// <param name="type"></param> private void PopPanel(UIPanelType type) { //如果栈里面为空,则返回 if (_StackPanel.Count <= 0) return; BasePanel basePanel = GetPanel(type); BasePanel topPanel = _StackPanel.Peek(); //如果当前要出栈的界面跟栈顶界面相同时 才会出栈 if(basePanel.gameObject == topPanel.gameObject) { _StackPanel.Pop(); topPanel.OnExit(); //如果出栈后栈里面还有界面则恢复 if(_StackPanel.Count >= 1) { _StackPanel.Peek().OnResume(); } } else { Debug.LogError("栈顶界面不是此界面,请检查进出栈!!"); } } /// <summary> /// 显示界面 /// </summary> /// <param name="type"></param> public void ShowUIForms(UIPanelType type) { BasePanel basePanel = GetPanel(type); switch (basePanel.uiType.uiFormShowMode) { case UIFormShowMode.Normal: EnterUIFormsCache(type); break; //如果是反切换类型则入栈 case UIFormShowMode.ReverseChange: PushPanel(type); break; //如果是隐藏其他的类型,清空显示的界面 case UIFormShowMode.HideOther: HideOtherPanel(type); break; } } /// <summary> /// 隐藏界面 如果显示界面字典里面存在此界面 /// </summary> /// <param name="type"></param> public void HideUIForms(UIPanelType type) { BasePanel basePanel = GetPanel(type); switch (basePanel.uiType.uiFormShowMode) { case UIFormShowMode.Normal: HideUIFormsCache(type); break; //如果是反切换类型则出栈 case UIFormShowMode.ReverseChange: PopPanel(type); break; case UIFormShowMode.HideOther: HideUIFormsCache(type); break; } } /// <summary> /// 隐藏除此之外的Panel,如果不赋值则清空所有 /// </summary> /// <param name="type"></param> public void HideOtherPanel(UIPanelType type = UIPanelType.Null) { foreach (KeyValuePair<UIPanelType,BasePanel> item in _DicShowPanel) { item.Value.OnExit(); } _DicShowPanel.Clear(); if (type != UIPanelType.Null) { BasePanel basePanel = GetPanel(type); basePanel.OnEnter(); _DicShowPanel.Add(type, GetPanel(type)); } } /// <summary> /// 将UI加入到已显示面板的字典中 /// </summary> /// <param name="type"></param> private void EnterUIFormsCache(UIPanelType type) { //如果显示面板字典里面有当前面板则返回 if (_DicShowPanel.ContainsKey(type)) return; BasePanel basePanel = GetPanel(type); _DicShowPanel.Add(type, basePanel); basePanel.OnEnter(); } /// <summary> /// 将UI隐藏 /// </summary> /// <param name="type"></param> private void HideUIFormsCache(UIPanelType type) { //如果显示面板字典里面没有当前面板则返回 if (!_DicShowPanel.ContainsKey(type)) return; BasePanel basePanel = GetPanel(type); _DicShowPanel.Remove(type); basePanel.OnExit(); } /// <summary> /// 根据面板类型得到实例化的面板 /// </summary> /// <param name="type"></param> /// <returns></returns> private BasePanel GetPanel(UIPanelType type) { if (_DicPanel.ContainsKey(type)) { return _DicPanel[type]; } else { //如果找不到就找这个面板的prefab的路径,然后根据prefab去实例化面板 BasePanel panel; string panelPath = _DicPanelPath.GetValue(type); GameObject insGo = GameObject.Instantiate(Resources.Load(panelPath),Canvas) as GameObject; insGo.name = type.ToString(); panel = insGo.GetComponent<BasePanel>(); switch (panel.uiType.uIFormParentType) { case UIFormParentType.FUllScreen: insGo.transform.SetParent(_TraFullScreen); break; case UIFormParentType.Fixed: insGo.transform.SetParent(_TraFixed); break; case UIFormParentType.PopUp: insGo.transform.SetParent(_TraPopUp); break; } _DicPanel.Add(type, panel); return panel; } } #region 解析地址json 并存储到字典中 private void ParseUIPanelPathJson() { TextAsset text = Resources.Load<TextAsset>("UIPanelType"); JSONObject jSONObject = new JSONObject(text.text); if (_DicPanelPath == null) _DicPanelPath = new Dictionary<UIPanelType, string>(); foreach (JSONObject item in jSONObject.list) { string panelTypeString = item["panelTypeString"].str; string path = item["path"].str; UIPanelType uIPanelType = (UIPanelType)System.Enum.Parse(typeof(UIPanelType), panelTypeString); _DicPanelPath.Add(uIPanelType, path); } } #endregion }
using System.Collections; using System; using System.Collections.Generic; using UnityEngine; public class UIType { /// <summary> /// panel类别 /// </summary> public UIPanelType uiPanelType; /// <summary> /// Panel的显示方式,有正常显示,隐藏其他和反向切换 /// </summary> public UIFormShowMode uiFormShowMode = UIFormShowMode.Normal; /// <summary> /// 这个透明度暂时没用 /// </summary> public UIFormLucencyType uIFormLucencyType = UIFormLucencyType.Lucency; /// <summary> /// Panel的父物体类型 /// </summary> public UIFormParentType uIFormParentType = UIFormParentType.PopUp;
代码比较多,不过都有贴心的注释
文章来源: Unity3D基础UI框架