Unity UI框架

使用建造者模式来构建整个结构,由UIManager统一管理UIBase、UIWidget和UISubBase,UIManager本身使用的是单例模式。

UIManager

UIManager提供注册和注销方法,供UIBase、UIWidget和UISubBase组册使用。

外界调用UIBase、UIWidget和UISubBase只能通过UIManager。

UI的显示和切换功能也是在这里执行的。

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;

public class UIManager : MonoBehaviour
{
    public static UIManager instance;

    /// <summary>
    /// 主画布
    /// </summary>
    public Transform mainCanvas;

    private void Awake()
    {
        instance = this;
        uiWidgets = new Dictionary<string, Dictionary<string, UIWidget>>();
        mainCanvas = GameObject.FindGameObjectWithTag("MainCanvas").transform;
        
        if (uiBases == null)
        {
            // 初始化
            uiBases = new Dictionary<string, UIBase>();
        }
    }

    private void Update()
    {
        if (currentUIPanelOnStay != null)
        {
            currentUIPanelOnStay();
        }
    }

    /// <summary>
    /// 存储所有需要操作的部件
    /// </summary>
    private Dictionary<string, Dictionary<string, UIWidget>> uiWidgets;
    
    /// <summary>
    /// 获得Widget
    /// </summary>
    /// <param name="panelName"></param>
    /// <param name="widgetName"></param>
    /// <returns></returns>
    public UIWidget ObtainUIWidget(string panelName, string widgetName)
    {
        if (uiWidgets.ContainsKey(panelName))
        {
            return uiWidgets[panelName][widgetName];
        }

        return null;
    }

    /// <summary>
    /// 获取 UISubWidget
    /// </summary>
    /// <param name="panelName"></param>
    /// <param name="widgetName"></param>
    /// <param name="uiSubBaseName"></param>
    /// <param name="uiSubWidgetName"></param>
    /// <returns></returns>
    public UISubWidget ObtainUISubWidget(string panelName, string widgetName, string uiSubBaseName,
        string uiSubWidgetName)
    {
        UIWidget uiWidget = ObtainUIWidget(panelName, widgetName);

        if (uiWidget == null)
        {
            return null;
        }

        return uiWidget.ObtainUISubWidget(uiSubBaseName, uiSubWidgetName);
    }

    /// <summary>
    /// 注册Widget
    /// </summary>
    /// <param name="panelName"></param>
    /// <param name="widgetName"></param>
    /// <param name="uiWidget"></param>
    public void RegisterUIWidget(string panelName, string widgetName, UIWidget uiWidget)
    {
        if (!uiWidgets.ContainsKey(panelName))
        {
            uiWidgets[panelName] = new Dictionary<string, UIWidget>();
        }

        uiWidgets[panelName].Add(widgetName, uiWidget);
    }

    /// <summary>
    /// 注销Widget
    /// </summary>
    /// <param name="panelName"></param>
    /// <param name="widgetName"></param>
    public void UnregisterUIWidget(string panelName, string widgetName)
    {
        if (uiWidgets.ContainsKey(panelName))
        {
            if (uiWidgets[panelName].ContainsKey(widgetName))
            {
                uiWidgets[panelName].Remove(widgetName);
            }
        }
    }

    /// <summary>
    /// 注销Panel
    /// </summary>
    /// <param name="panelName"></param>
    public void UnregisterUIPanel(string panelName)
    {
        if (uiWidgets.ContainsKey(panelName))
        {
            uiWidgets[panelName].Clear();
            uiWidgets[panelName] = null;
            uiWidgets.Remove(panelName);
        }
    }

    /// <summary>
    /// 获取主画布
    /// </summary>
    /// <returns></returns>
    public Transform ObtainMainCanvas()
    {
        return mainCanvas;
    }

    #region UI Switch

    /// <summary>
    /// 当前显示的 UIPanel
    /// </summary>
    private string currentUIPanel;

    /// <summary>
    /// 当前 UIPanel 的更新方法
    /// </summary>
    private UnityAction currentUIPanelOnStay;

    /// <summary>
    /// 当前初始化的所有 UI
    /// </summary>
    private Dictionary<string, UIBase> uiBases;
    
    /// <summary>
    /// 切换到指定的 UIPanel
    /// </summary>
    /// <param name="panelName"></param>
    public void SwitchToPanel(string panelName)
    {
        // 如果当前 UIPanel 为要打开的 UIPanel
        if (currentUIPanel == panelName)
        {
            return;
        }

        // 如果 UIPanel 没有创建
        if (!uiBases.ContainsKey(panelName))
        {
            CreateUIPanel(panelName);
        }
        
        // 切换显示的 UIPanel
        if (currentUIPanel != null)
        {
            HideUIPanel(currentUIPanel);
        }
        
        DisplayUIPanel(panelName);
    }

    /// <summary>
    /// 创建新的 UIPanel
    /// </summary>
    /// <param name="prefabName"></param>
    private void CreateUIPanel(string prefabName)
    {
        GameObject prefab = ResourceAndDataManager.Instance.ObtainPrefab(prefabName);
        
        // 生成对象
        GameObject gameObject = Instantiate(prefab);
        
        // 取出掉 "(Clone)"
        gameObject.name = StringTool.CullClone(gameObject.name);
        
        // 设置 Rotation
        gameObject.transform.rotation = Quaternion.identity;
        
        // 设置父对象
        gameObject.transform.SetParent(ObtainMainCanvas(), false);

        // 添加创建的 UIPanel 到字典
        uiBases.Add(prefabName, gameObject.GetComponent<UIBase>());
    }

    /// <summary>
    /// 显示 UIPanel
    /// </summary>
    /// <param name="panelName"></param>
    private void DisplayUIPanel(string panelName)
    {
        // 设置当前显示的 UIPanel
        currentUIPanel = panelName;
        
        uiBases[currentUIPanel].OnEnter();

        // 设置当前 UIPanel 更新方法
        currentUIPanelOnStay = uiBases[currentUIPanel].OnStay;
    }

    /// <summary>
    /// 隐藏 UIPanel
    /// </summary>
    /// <param name="panelName"></param>
    private void HideUIPanel(string panelName)
    {
        uiBases[panelName].OnExit();
    }
    
    /// <summary>
    /// 获取当前显示的 UIPanel 名称
    /// </summary>
    /// <returns></returns>
    public string ObtainCurrentUIPanelName()
    {
        return currentUIPanel;
    }

    /// <summary>
    /// 获取当前显示的 UIPanel
    /// </summary>
    /// <returns></returns>
    public UIBase ObtainCurrentUIPanel()
    {
        return uiBases[currentUIPanel];
    }

    /// <summary>
    /// 通过名称获取 UIPanel
    /// </summary>
    /// <param name="uiPanelName"></param>
    /// <returns></returns>
    public UIBase ObtainUIPanelByName(string uiPanelName)
    {
        return uiBases[uiPanelName];
    }
    
    #endregion
}

UIBase

所有UIController的基类。

包括进入、停留、离开回调方法,提供调用UIWidget自身方法来获取和修改Panel下面组件的方法,添加Panel下面组件的各种事件。

搜索自身所有下级游戏对象,给标记了特定后缀(我这里设置的是"_N")的游戏对象添加UIWidget。

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;

public class UIBase : MonoBehaviour
{
    private CanvasGroup canvasGroup;
    
    public virtual void Awake()
    {
        canvasGroup = GetComponent<CanvasGroup>();
        
        // 在所有需要操作的部件上添加UIWidget脚本
        Transform[] children = GetComponentsInChildren<Transform>();
       
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值