简单的ui基类
UIBasePanel.cs
csharp
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
csharp
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);
}
}
}