UGUI搭建界面功能 (一) 提供接口
基本类:
1.UIType 存放UI的枚举,枚举的类型与UI预制体的名字要相同;
2.Singleton 封装一个单例的父类,所有只要继承了这个类的脚本就是单例;
3.SingletonUI UI单例的父类,同时这个类继承于Singleton;
4.UIEventListener 这个类继承MonoBehaviour,用于监听点击、拖拽等功能
5.BaseUI UI的父类,所有UI界面的UI脚本都要继承这个类;
6.UIManager UI管理类
7.GameManager 游戏管理类
-----------------------------------接下来!---------------------上代码!------------------------------------
1.UIType
/// <summary> /// UI的枚举 放UI预制体的名字 /// </summary> public enum UIType { None, LoginUI, MainUI, SetUI, SetUI2, }
(枚举的内容根据实际情况而定)
2.Singleton(注意引用)
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; /// <summary> /// 单例的父类 所有单例继承 /// </summary> public class Singleton <T> { //反射 private static T _instance = Activator.CreateInstance<T>();// 相当于 new T(); public static T Instance { get { //在这里可以直接return 因为在前面已经创建了,所以不会出现null的情况 return _instance; } } }
(因为这个类不继承MonoBehaviour,所以不能直接通过new创建出来,要通过反射创建出来)
3.UIEventListener
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 using UnityEngine.UI; 5 using UnityEngine.EventSystems; 6 using System; 7 8 /// <summary> 9 /// 监听游戏物体点击、拖拽等功能的组件 10 /// </summary> 11 public class UIEventListener : MonoBehaviour,IPointerExitHandler,IPointerEnterHandler,IPointerClickHandler, IPointerDownHandler, IPointerUpHandler,IBeginDragHandler, IEndDragHandler,IDragHandler 12 { 13 //相应的委托 14 public Action<GameObject, PointerEventData> onClick; 15 public Action<GameObject, PointerEventData> onDown; 16 public Action<GameObject, PointerEventData> onEnter; 17 public Action<GameObject, PointerEventData> onExit; 18 public Action<GameObject, PointerEventData> onUp; 19 public Action<GameObject, PointerEventData> onBeginDrag; 20 public Action<GameObject, PointerEventData> onDrag; 21 public Action<GameObject, PointerEventData> onEndDrag; 22 23 public static UIEventListener Get(GameObject go) 24 { 25 UIEventListener evt = go.GetComponent<UIEventListener>();//得到这个组建 26 if (evt == null)//判断是否为空 27 { 28 evt = go.AddComponent<UIEventListener>();//不存在就添加 29 } 30 return evt; 31 } 32 33 //实现接口 34 public void OnBeginDrag(PointerEventData eventData) 35 { 36 if (onBeginDrag != null)//判断如果不为空,就执行委托 37 { 38 onBeginDrag(gameObject, eventData); 39 } 40 } 41 42 public void OnDrag(PointerEventData eventData) 43 { 44 if (onDrag != null) 45 { 46 onDrag(gameObject, eventData); 47 } 48 } 49 50 public void OnEndDrag(PointerEventData eventData) 51 { 52 if (onEndDrag != null) 53 { 54 onEndDrag(gameObject, eventData); 55 } 56 } 57 58 public void OnPointerClick(PointerEventData eventData) 59 { 60 61 if (onClick != null) 62 { 63 onClick(gameObject, eventData); 64 } 65 } 66 67 public void OnPointerDown(PointerEventData eventData) 68 { 69 if (onDown != null) 70 { 71 onDown(gameObject, eventData); 72 } 73 } 74 75 public void OnPointerEnter(PointerEventData eventData) 76 { 77 if (onEnter != null) 78 { 79 onEnter(gameObject, eventData); 80 } 81 } 82 83 public void OnPointerExit(PointerEventData eventData) 84 { 85 if (onExit != null) 86 { 87 onExit(gameObject, eventData); 88 } 89 } 90 91 public void OnPointerUp(PointerEventData eventData) 92 { 93 if (onUp != null) 94 { 95 onUp(gameObject, eventData); 96 } 97 } 98 }
(后续需要其他功能可以继续封装,注意继承一个就要写一个接口和一个委托)
4.BaseUI
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 using UnityEngine.UI; 5 6 /// <summary> 7 /// UI的父类 8 /// </summary> 9 public class BaseUI 10 { 11 private GameObject m_go;//对应要操作的游戏物体 12 13 private Canvas m_canvas;//挂载的画布 14 15 private bool m_done;//用来判断是否加载完成 16 17 private bool m_isShow;//判断是否显示UI 18 19 protected int m_sort_order;//界面显示的层 20 21 private Dictionary<string, GameObject> m_cache_gos;//缓存池 存储已经获取过的游戏物体 22 23 //下面是属性 24 public virtual string uiName 25 { 26 get 27 { 28 return UIType.None.ToString(); 29 } 30 } 31 32 public bool IsShow 33 { 34 get 35 { 36 return m_isShow; 37 } 38 set 39 { 40 m_isShow = value; 41 } 42 } 43 44 public bool IsDone 45 { 46 get 47 { 48 return m_done; 49 } 50 set 51 { 52 m_done = value; 53 } 54 } 55 56 57 /// <summary> 58 /// 关闭界面 59 /// </summary> 60 public virtual void Close() 61 { 62 IsShow = false; 63 IsDone = false; 64 m_canvas = null; 65 m_cache_gos.Clear(); 66 67 //将注册的事件清空 68 UIEventListener[] evts = m_go.GetComponentsInChildren<UIEventListener>(); 69 for (int i = 0; i < evts.Length; i++) 70 { 71 evts[i].onClick = null; 72 evts[i].onDown = null; 73 evts[i].onDrag = null; 74 evts[i].onBeginDrag = null; 75 evts[i].onEnter = null; 76 evts[i].onEndDrag = null; 77 evts[i].onExit = null; 78 evts[i].onUp = null; 79 } 80 81 //删除游戏物体 82 GameObject.Destroy(m_go); 83 m_go = null; 84 //从列表中移除 85 UIManager.Instance.RemoveUI(this); 86 } 87 88 /// <summary> 89 /// 显示界面 90 /// </summary> 91 public virtual void Show() 92 { 93 IsShow = true; 94 if (m_canvas != null) 95 { 96 m_canvas.enabled = true; 97 } 98 } 99 100 /// <summary> 101 /// 隐藏界面 102 /// </summary> 103 public virtual void Hide() 104 { 105 IsShow = false; 106 if (m_canvas != null) 107 { 108 m_canvas.enabled = false; 109 } 110 } 111 112 113 public virtual void OnUpdate(float dt) 114 { 115 //判断没有初始化完或者是没有显示的时候就不能执行这个方法 116 if (IsShow == false || IsDone == false) 117 { 118 return; 119 } 120 } 121 122 //相当于Awake() 123 public virtual void Init() 124 { 125 //这个要在子类重写,所以这里不用写 126 } 127 128 /// <summary> 129 /// 加载游戏物体 130 /// </summary> 131 /// <param name="go">要加载的物体</param> 132 public void OnLoad(GameObject go) 133 { 134 IsShow = true;//加载之后默认显示 135 m_go = go; 136 m_cache_gos = new Dictionary<string, GameObject>();//实例化缓存池 137 138 //找到自己身上的一个画布Canvas 用来做显示与否 139 m_canvas = Find<Canvas>(m_go); 140 if (m_canvas == null) 141 { 142 m_canvas = m_go.AddComponent<Canvas>(); 143 } 144 m_canvas.overrideSorting = true;//设置层级 145 146 m_canvas.sortingOrder = m_sort_order;//设置显示层级 147 148 //添加UI射线检测的组建 因为加上画布之后如果没有这个就点击不了 149 if (m_go.GetComponent<GraphicRaycaster>() == null) 150 { 151 m_go.AddComponent<GraphicRaycaster>(); 152 } 153 154 //调用初始化的方法 155 Init(); 156 IsDone = true;//加载完成 157 158 Show(); 159 } 160 161 /// <summary> 162 /// 找游戏物体 163 /// </summary> 164 /// <param name="name">传入要找的物体的名字</param> 165 /// <returns></returns> 166 public GameObject Find(string name) 167 { 168 if (m_cache_gos.ContainsKey(name))//先用键判断字典里面有木有 169 { 170 return m_cache_gos[name];//有就返回出来 171 } 172 173 GameObject o = m_go.transform.Find(name).gameObject;//没有就找 174 m_cache_gos.Add(name, o);//再传进来 175 return o; 176 177 } 178 179 /// <summary> 180 /// 传入物体,找这个物体身上的组建 181 /// </summary> 182 /// <typeparam name="T">要找到的组建</typeparam> 183 /// <param name="go">传入的物体</param> 184 /// <returns></returns> 185 public T Find<T>(GameObject go)where T : Component 186 { 187 return go.GetComponent<T>(); 188 } 189 190 191 public T Find<T>(string name)where T : Component 192 { 193 GameObject o = Find(name); 194 return Find<T>(o); 195 } 196 197 198 public UIEventListener Register(GameObject go) 199 { 200 return UIEventListener.Get(go); 201 } 202 203 /// <summary> 204 /// 注册的方法 205 /// </summary> 206 /// <param name="name"></param> 207 /// <returns></returns> 208 public UIEventListener Register(string name) 209 { 210 return UIEventListener.Get(Find(name)); 211 } 212 }
5.SingletonUI
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 5 /// <summary> 6 /// UI的单例的父类 7 /// </summary> 8 public class SingletonUI<T>:BaseUI where T : BaseUI 9 { 10 public static T Instance; 11 12 //通过构造函数赋值 13 public SingletonUI() 14 { 15 Instance = this as T; 16 } 17 18 /// <summary> 19 /// 重写父类的方法 20 /// </summary> 21 public override void Close() 22 { 23 base.Close(); 24 Instance = null; 25 } 26 }
6.UIManager
1 using System.Collections; 2 using System.Collections.Generic; 3 using UnityEngine; 4 using System; 5 6 /// <summary> 7 /// UI管理类 因为Singleton是不挂游戏物体的,所以继承之后不用挂载 直接new出来 8 /// </summary> 9 public class UIManager : Singleton<UIManager> 10 { 11 private List<BaseUI> m_ui_list;//存储UI对象的集合 12 13 private Transform parentTf;//生成物所在的父级 14 15 public List<BaseUI> uiList//m_ui_list的属性 16 { 17 get 18 { 19 return m_ui_list; 20 } 21 } 22 23 //初始化的方法 24 public void Init() 25 { 26 m_ui_list = new List<BaseUI>();//实力化这个集合 27 parentTf = GameObject.Find("Canvas").transform;//找到这个画布摄像机当作父级 28 } 29 30 //相当于Update 31 public void OnUpdate(float dt) 32 { 33 for (int i = m_ui_list.Count-1; i>=0; i--) 34 { 35 m_ui_list[i].OnUpdate(dt); 36 } 37 } 38 39 //添加ui到m_ui_list集合里面 40 public void AddUI(BaseUI ui) 41 { 42 //先判断要加进去的ui有没有在集合里面 43 int index = m_ui_list.IndexOf(ui); 44 if (index == -1)//如果不存在 45 { 46 m_ui_list.Add(ui); 47 } 48 } 49 50 //移除m_ui_list集合里面的UI 51 public void RemoveUI(BaseUI ui) 52 { 53 m_ui_list.Remove(ui); 54 } 55 56 //关闭UI 57 public void CloseUI(BaseUI ui) 58 { 59 ui.Close(); 60 } 61 62 //关闭所有ui 63 public void CloseAllUI() 64 { 65 for (int i = m_ui_list.Count-1; i >=0; i--) 66 { 67 m_ui_list[i].Close(); 68 } 69 } 70 71 //找UI 通过类型 72 public BaseUI FindUI(UIType type) 73 { 74 for (int i = 0; i < m_ui_list.Count; i++) 75 { 76 if (m_ui_list[i].uiName == type.ToString()) 77 { 78 return m_ui_list[i]; 79 } 80 } 81 82 return null; 83 } 84 85 //找UI 通过名字 86 public BaseUI FindUI(string uiName) 87 { 88 for (int i = 0; i < m_ui_list.Count; i++) 89 { 90 if (m_ui_list[i].uiName == uiName) 91 { 92 return m_ui_list[i]; 93 } 94 } 95 96 return null; 97 } 98 99 //创建UI 100 public BaseUI CreateUI(UIType type) 101 { 102 //要创建的游戏物体 103 GameObject obj = MonoBehaviour.Instantiate(Resources.Load("UI/" + type.ToString()), parentTf, false) as GameObject; 104 105 BaseUI ui = Activator.CreateInstance(Type.GetType(type.ToString())) as BaseUI;//相当于创建的是LoginUI的时候 Login ui =new LoginUI(); 106 107 ui.OnLoad(obj); 108 109 return ui; 110 } 111 112 //显示界面 113 public void ShowUI(UIType type) 114 { 115 BaseUI ui = FindUI(type); 116 117 if(ui == null)//如果这个界面不存在 118 { 119 ui = CreateUI(type); 120 //添加到集合里面 121 m_ui_list.Add(ui); 122 } 123 else 124 { 125 ui.Show(); 126 } 127 128 } 129 130 //隐藏界面 131 public void HideUI(UIType type) 132 { 133 BaseUI ui = FindUI(type); 134 if (ui != null) 135 { 136 ui.Hide(); 137 } 138 }