简单的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]);
                else
                    controlDic.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);
        }
    }
}
01-27 12:26