实现简易的UI管理,适合单机。
UIMgr
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
| using System.Collections.Generic; using UnityEngine;
public class UIMgr : NormalSingleton<UIMgr> { private Canvas canvas; public Canvas Canvas => canvas;
private Stack<string> uiStack = new Stack<string>(); private Dictionary<string,IView> viewsDic = new Dictionary<string,IView>(); public void Init(Canvas canvas) { this.canvas = canvas; } public IView Show(string path) { if(uiStack.Count > 0) { string pre = uiStack.Peek(); viewsDic[pre].Hide(); } IView view = InitView(path); if (view != null) { view.Show(); uiStack.Push(path); viewsDic[path] = view; } return view; } private IView InitView(string path) { if (viewsDic.ContainsKey(path)) { return viewsDic[path]; } else { GameObject go = LoadMgr.Instance.LoadPrefab(path,Canvas.transform); if (go != null) { System.Type type = BindUtil.GetPrefabType(path); if (type != null) { IView view = (IView)go.AddComponent(type); view.Init(); return view; } else Debug.LogError("此Prefab没有对应的View脚本:" + path); return null; } else Debug.LogError("没有找到对应的Prefab:" + path); return null; } } public void Back() { if(uiStack.Count <=1) { return; } string name = uiStack.Pop(); viewsDic[name].Hide();
name = uiStack.Peek(); viewsDic[name].Show(); } }
|
View层
IView
View层包含所有UI元素的引用,使用统一的IView接口。
1 2 3 4 5 6
| public interface IView { void Init(); void Show(); void Hide(); }
|
ViewBase
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| using UnityEngine;
public class ViewBase : MonoBehaviour, IView { private UIUtil m_UIUtil; protected UIUtil UIUtil { get { if (m_UIUtil == null) { m_UIUtil = gameObject.AddComponent<UIUtil>(); m_UIUtil.Init(); } return m_UIUtil; } } public virtual void Init() { } public virtual void Hide() { gameObject.SetActive(false); }
public virtual void Show() { gameObject.SetActive(true); } }
|
UIUtil
用来处理UI查找子物体的操作,并且声明了UIUtilData
中间类,存储了一个UI元素的可交互信息,这个中间类还分离了给按钮添加添加监听和修改Image的Sprite的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using TMPro;
public class UIUtil : MonoBehaviour { private Dictionary<string, UIUtilData> dataDic; public void Init() { dataDic = new Dictionary<string, UIUtilData>(); RectTransform rectTransform = transform.GetComponent<RectTransform>(); foreach (RectTransform item in rectTransform) { dataDic.Add(item.name, new UIUtilData(item)); } } public UIUtilData Get(string name) { UIUtilData data; if(dataDic.TryGetValue(name, out data)) return data; else { Transform temp = transform.Find(name); if(temp != null) { dataDic.Add(name,new UIUtilData(temp.GetComponent<RectTransform>())); return dataDic[name]; } else { Debug.LogError("无法查找到物体:" + name); return null; } } } } public class UIUtilData { public GameObject Go { get; private set; } public RectTransform RectTransform { get; private set; } public Button Btn { get; private set; } public Image Img { get; private set; } public TextMeshProUGUI TextMeshProUGUI { get; private set; } public UIUtilData(RectTransform rectTransform) { Go = rectTransform.gameObject; RectTransform = rectTransform; Btn = rectTransform.GetComponent<Button>(); Img = rectTransform.GetComponent<Image>(); TextMeshProUGUI = rectTransform.GetComponent<TextMeshProUGUI>(); }
public void AddListener(System.Action action) { if(Btn != null) { Btn.onClick.AddListener(()=> action.Invoke()); } else { Debug.LogError("当前物体没有Button组件:" + Go.name); } }
public void SetSprite(Sprite sprite) { if(Img != null) { Img.sprite = sprite; } else { Debug.LogError("当前物体没有Image组件:" + Go.name); } } }
|
使用
StartView
脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| [BindPrefab(Path.START_VIEW)] public class StartView : ViewBase { void Start() { }
void Update() { } }
|
GameRoot
1 2 3 4 5 6 7 8 9 10 11
| public class GameRoot : MonoBehaviour { public GameObject canvas; private void Start() { InitCustomAttributes initCustomAttributes = new InitCustomAttributes(); initCustomAttributes.Init(); UIMgr.Instance.Init(GetComponent<Canvas>()); UIMgr.Instance.Show(Pathes.START_VIEW); } }
|