简单的ui基类
UIBasePanel.cs
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;namespace MYTOOL.UI
{public class UIBasePanel : MonoBehaviour{//通过里式转换原则 来存储所有的控件private readonly Dictionary<string, List<UIBehaviour>> controlDic = Pool<Dictionary<string, List<UIBehaviour>>>.Get();private bool dirty = true;#region >> Unity 生命周期函数protected virtual void Awake(){FindChildrenControl<Button>();FindChildrenControl<Image>();FindChildrenControl<Text>();FindChildrenControl<Toggle>();FindChildrenControl<Slider>();FindChildrenControl<ScrollRect>();FindChildrenControl<InputField>();OnAwake();}protected virtual void Start(){OnStart();}protected virtual void Update(){if (dirty){dirty = false;OnDirty();}OnUpdate();}protected virtual void OnDestroy(){OnClose();controlDic.Clear();Pool<Dictionary<string, List<UIBehaviour>>>.Release(controlDic);}#endregion Unity 生命周期函数#region >> 生命周期函数(需子类重写)/// <summary>/// Awake生命周期/// </summary>protected virtual void OnAwake() { }/// <summary>/// Start生命周期/// </summary>protected virtual void OnStart() { }/// <summary>/// Update生命周期/// </summary>protected virtual void OnUpdate() { }/// <summary>/// Update生命周期中执行OnDirty/// </summary>protected virtual void OnDirty() { }/// <summary>/// OnDestroy生命周期/// </summary>protected virtual void OnClose() { }protected virtual void OnShow() { }protected virtual void OnHide() { }protected virtual void OnClick(string btnName) { }protected virtual void OnValueChanged(string toggleName, bool value) { }#region >> 复制子类重写函数/*protected override void OnAwake() { }protected override void OnStart() { }protected override void OnUpdate() { }protected override void OnDirty() { }protected override void OnClose() { }protected override void OnShow() { }protected override void OnHide() { }protected override void OnClick(string btnName) { }protected override void OnValueChanged(string toggleName, bool value) { }*/#endregion 复制子类重写函数#endregion 生命周期函数(需子类重写)/// <summary>/// 显示自己/// </summary>public void ShowMe(){gameObject.SetActive(true);OnShow();}/// <summary>/// 隐藏自己/// </summary>public void HideMe(){gameObject.SetActive(false);OnHide();}public void SetDirty(){dirty = true;}/// <summary>/// 得到对应名字的对应控件脚本/// </summary>/// <typeparam name="T"></typeparam>/// <param name="controlName"></param>/// <returns></returns>protected T GetControl<T>(string controlName) where T : UIBehaviour{if (controlDic.ContainsKey(controlName)){for (int i = 0; i < controlDic[controlName].Count; ++i){if (controlDic[controlName][i] is T)return controlDic[controlName][i] as T;}}return null;}/// <summary>/// 找到子对象的对应控件/// </summary>/// <typeparam name="T"></typeparam>private void FindChildrenControl<T>() where T : UIBehaviour{T[] controls = this.GetComponentsInChildren<T>();for (int i = 0; i < controls.Length; ++i){string objName = controls[i].gameObject.name;if (!objName.StartsWith('@')){continue;}else{objName = objName.Substring(1);}if (controlDic.ContainsKey(objName))controlDic[objName].Add(controls[i]);elsecontrolDic.Add(objName, new List<UIBehaviour>() { controls[i] });//如果是按钮控件if (controls[i] is Button){(controls[i] as Button).onClick.AddListener(() =>{OnClick(objName);});}//如果是单选框或者多选框else if (controls[i] is Toggle){(controls[i] as Toggle).onValueChanged.AddListener((value) =>{OnValueChanged(objName, value);});}}}}
}
Pool.cs
using System.Collections.Generic;namespace MYTOOL.UI
{public class ObjectPool<T> where T : new(){private readonly Stack<T> _stack = new Stack<T>();private readonly System.Action<T> _actionOnGet;private readonly System.Action<T> _actionOnRelease;public int CountAll { get; private set; }public int CountInactive { get { return _stack.Count; } }public int CountActive{get{return CountAll - CountInactive;}}public ObjectPool(System.Action<T> actionOnGet, System.Action<T> actionOnRelease){_actionOnGet = actionOnGet;_actionOnRelease = actionOnRelease;}public T Get(){T element;if (_stack.Count == 0){element = new T();CountAll++;}else{element = _stack.Pop();}if (_actionOnGet != null){_actionOnGet(element);}return element;}public void Release(T element){if (_stack.Count > 0 && ReferenceEquals(_stack.Peek(), element)){UnityEngine.Debug.LogError("Internal error. Trying to destroy object that is already released to pool.");}if (_actionOnRelease != null){_actionOnRelease(element);}_stack.Push(element);}}public static class ListPool<T>{private static readonly ObjectPool<List<T>> _listPool = new ObjectPool<List<T>>(null, Clear);private static void Clear(List<T> l) { l.Clear(); }public static List<T> Get(){return _listPool.Get();}public static void Release(List<T> toRelease){_listPool.Release(toRelease);}}public static class Pool<T> where T : new(){private static readonly ObjectPool<T> _objectPool = new ObjectPool<T>(null, null);public static T Get(){return _objectPool.Get();}public static void Release(T element){_objectPool.Release(element);}}
}