核心内容
UIType.cs
namespace MYTOOL.UI
{
/// <summary>
/// UI层级
/// </summary>
public enum UILayer
{
/// <summary>
/// 主界面层
/// </summary>
MainUI = 0,
/// <summary>
/// 普通界面层
/// </summary>
NormalUI = 1,
/// <summary>
/// 弹出层
/// </summary>
PopupUI = 2,
/// <summary>
/// Top层 高于弹出层
/// </summary>
Top = 3,
/// <summary>
/// 加载层 加载进度或加载动画
/// </summary>
Loading = 4,
}
/// <summary>
/// UI组
/// </summary>
public enum UIGroup
{
Default = 0,
//TODO
}
}
UIBase.cs
using UnityEngine;
namespace MYTOOL.UI
{
[DisallowMultipleComponent]
[RequireComponent(typeof(RectTransform))]
public abstract class UIBase : MonoBehaviour
{
/// <summary>
/// UI层级
/// </summary>
public virtual UILayer Layer {
get; } = UILayer.NormalUI;
/// <summary>
/// UI组
/// </summary>
public virtual UIGroup Group {
get; } = UIGroup.Default;
/// <summary>
/// 同一层单独存在
/// </summary>
public virtual bool IsOnly {
get; } = false;
/// <summary>
/// 总显示
/// </summary>
public virtual bool AlwaysDisplay {
get; } = false;
/// <summary>
/// UI隐藏所需时间
/// </summary>
public virtual float UIHideTime {
get; } = 0;
/// <summary>
/// UI关闭所需时间
/// </summary>
public virtual float UICloseTime {
get; } = 0;
/// <summary>
/// UI名称
/// </summary>
public string UIName {
get; private set; }
private bool dirty = true;
/// <summary>
/// 脏标记
/// </summary>
public void SetDirty()
{
dirty = true;
}
protected virtual void Update()
{
if (dirty)
{
dirty = false;
OnDirty();
OnRefresh();
}
OnUpdate();
}
/// <summary>
/// 创建时执行一次
/// </summary>
protected abstract void OnCreate();
/// <summary>
/// 显示UI
/// </summary>
protected virtual void OnShow() {
}
/// <summary>
/// 隐藏UI
/// </summary>
protected virtual void OnHide() {
}
/// <summary>
/// 关闭UI/销毁UI
/// </summary>
protected virtual void OnClose() {
}
/// <summary>
/// 每帧执行
/// </summary>
protected virtual void OnUpdate() {
}
/// <summary>
/// 刷新其它
/// </summary>
protected virtual void OnDirty() {
}
/// <summary>
/// 刷新UI
/// </summary>
protected virtual void OnRefresh() {
}
/// <summary>
/// 进入效果(显示)
/// </summary>
protected virtual void OnEnterEffect() {
}
/// <summary>
/// 隐藏效果
/// </summary>
protected virtual void OnHideEffect() => OnExitEffect();
/// <summary>
/// 退出效果(隐藏/关闭)
/// </summary>
protected virtual void OnExitEffect() {
}
#region >> 内部方法
protected RectTransform root;
internal void InitUI(string uiName)
{
root = GetComponent<RectTransform>();
root.localPosition = Vector3.zero;
root.localScale = Vector3.one;
root.anchorMin = Vector2.zero;
root.anchorMax = Vector2.one;
root.offsetMin = Vector2.zero;
root.offsetMax = Vector2.zero;
UIName = uiName;
OnCreate();
}
internal void ShowUI()
{
gameObject.SetActive(true);
transform.SetAsLastSibling();
OnEnterEffect();
OnShow();
}
internal void HideUI()
{
if (AlwaysDisplay)
{
Debug.LogWarning("Can't hide");
return;
}
if (UIHideTime > 0)
{
OnHideEffect();
OnHide();
this.Seconds(UIHideTime, () => gameObject.SetActive(false));
}
else
{
OnHide();
gameObject.SetActive(false);
}
}
internal void CloseUI()
{
if (UICloseTime > 0)
{
OnExitEffect();
}
OnClose();
Destroy(gameObject, UICloseTime);
}
internal void RefreshUI()
{
SetDirty();
}
#endregion
}
}
UIManager.cs
using System;
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using UnityEngine;
namespace MYTOOL.UI
{
/// <summary>
/// UI管理类
/// </summary>
public partial class UIManager : MonoBehaviour
{
/// <summary>
/// UI预设加载函数
/// </summary>
public Func<string, GameObject> ResLoaderFunc = uiPath => ResLoader.Ins.Load<GameObject>(uiPath, true);
/// <summary>
/// UI预设基础路径格式
/// </summary>
private const string UI_PREFAB_PATH_FORMAT = "UI/{0}";
/// <summary>
/// UI预设模块路径格式
/// </summary>
private const string UI_PREFAB_MODULE_PATH_FORMAT = "UI/{0}/{1}";
#region >> 私有变量
private Transform MainParent;
private Transform NormalParent;
private Transform PopParent;
private Transform TopParent;
private Transform LoadingParent;
private readonly Dictionary<string, UIBase> UIBaseMap = new Dictionary<string, UIBase>();
private UIBase CurrentMainUI;
private readonly List<UIBase> NormalUIList = new List<UIBase>(16);
private readonly List<UIBase> PopUIList = new List<UIBase>(16);
#endregion
private static UIManager _instace;
public static UIManager Ins => Instance;
public static UIManager Instance
{
get
{
if (_instace == null)
{
var canvasPrefab = Resources.Load<GameObject>("MainCanvas");
var canvsGo = Instantiate(canvasPrefab);
canvsGo.name = "MainCanvas";
if (!canvsGo.TryGetComponent<UIManager>(out _instace))
{
_instace = canvsGo.AddComponent<UIManager>();
}
_instace.OnInit();
if (DebugMode) LogInfo($"UIManager initalize !");
DontDestroyOnLoad(_instace);
}
return _instace;
}
}
private void OnInit()
{
MainParent = transform.Find("MainUI");
NormalParent = transform.Find("NormalUI");
PopParent = transform.Find("PopupUI");
TopParent = transform.Find("Top");
LoadingParent = transform.Find("Loading");
}
private void OnDestroy()
{
UIBaseMap.Clear();
NormalUIList.Clear();
PopUIList.Clear();
}
/// <summary>
/// 获取UI相机
/// </summary>
/// <returns></returns>
public Camera GetUICamera()
{
Canvas canvas = GetComponent<Canvas>();
if (canvas.worldCamera)
return canvas.worldCamera;
return Camera.main;
}
public Transform GetUIParent(UILayer layer)
{
return layer switch
{
UILayer.MainUI => MainParent,
UILayer.NormalUI => NormalParent,
UILayer.PopupUI => PopParent,
UILayer.Top => TopParent,
UILayer.Loading => LoadingParent,
_ => transform,
};
}
#region >> 显示UI
/// <summary>
/// 显示UI
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public T ShowUI<T>() where T : UIBase
{
return InternalShowUI<T>(typeof(T).Name, string.Empty);
}
/// <summary>
/// 显示UI
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="uiName">UI名称/预制体名称</param>
/// <returns></returns>
public T ShowUI<T>(string uiName) where T : UIBase
{
return InternalShowUI<T>(uiName, string.Empty);
}
/// <summary>
/// 显示模块UI
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="modulePath">模块路径</param>
/// <returns></returns>
public T ShowModuleUI<T>(string modulePath) where T : UIBase
{
return InternalShowUI<T>(typeof(T).Name, modulePath);
}
/// <summary>
/// 显示模块UI
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="uiName">UI名称/预制体名称</param>
/// <param name="modulePath">模块路径</param>
/// <returns></returns>
public T ShowModuleUI<T>(string uiName, string modulePath)