【Unity框架】手搓UI框架(TransformHelper,UIEventListener,UIWindow,UIMgr)

框架

所谓框架就是搭建好一个架子,拆箱即用,直接上手,像使用工具一样十分方便

0. 资源链接

UI框架学习 手搓UI框架(TransformHelper,UIEventListener,UIWindow,UIMgr)

1. TransformHelper

using UnityEngine;

namespace FrameWorkStudy.Utils
{
    /// <summary>
    /// 变换组件(Transform)工具类
    /// </summary>
    public static class TransformHelper
    {
        /// <summary>
        /// 通过子节点名字递归查找节点
        /// </summary>
        /// <param name="parentRoot">this修饰, 作为Transform扩展方法</param>
        /// parentRoot.FindChildByName(childName) <=> TransformHelper.FindChildByName(parentRoot, childName)
        /// <param name="childName">节点名称</param>
        /// <returns></returns>
        public static Transform FindChildByName(this Transform parentRoot, string childName)
        {
            var tf = parentRoot.Find(childName);
            if (tf != null) return tf;
            for (int i = 0; i < parentRoot.childCount; i++)
            {
                tf = FindChildByName(parentRoot.GetChild(i), childName);
                if (tf != null) return tf;
            }
            return null;
        }
        
        // 以后如果有其他工具函数也写在这里,例如旋转,缩放...
    }
}

2. UIEventListener

using System;
using UnityEngine;
using UnityEngine.EventSystems;

namespace FrameWorkStudy.Event
{
    /// <summary>
    /// UI事件监听类
    /// </summary>
    public class UIEventListener : MonoBehaviour, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler // 可以继续实现接口IDragHandler,需要什么事件就实现什么接口
    {
        public event Action<PointerEventData> OnClickAction; // 点击
        public event Action<PointerEventData> OnUpAction; // 抬起
        public event Action<PointerEventData> OnDownAction; // 按下

        public static UIEventListener GetEventListener(Transform tf)
        {
            var uiEvent = tf.GetComponent<UIEventListener>();
            if (uiEvent == null)
            {
                uiEvent = tf.gameObject.AddComponent<UIEventListener>();
            }
            return uiEvent;
        }

        public void OnPointerClick(PointerEventData eventData)
        {
            OnClickAction?.Invoke(eventData);
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            OnDownAction?.Invoke(eventData);
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            OnUpAction?.Invoke(eventData);
        }
    }
}

UIEventListener可以仿造EventTrigger写,EventTrigger所包含的事件是比较全的

    public class EventTrigger : MonoBehaviour,
    IPointerEnterHandler, IPointerExitHandler,
    IPointerDownHandler, IPointerUpHandler, IPointerClickHandler,
    IInitializePotentialDragHandler,
    IBeginDragHandler, IDragHandler, IEndDragHandler,
    IDropHandler,
    IScrollHandler,
    IUpdateSelectedHandler, ISelectHandler, IDeselectHandler,
    IMoveHandler,
    ISubmitHandler, ICancelHandler
    {
    	// ...
    }

但是通过在面板中点击AddComponent添加EventTrigger发现,这是要手动拖函数实现**(例如点击)**事件回调,而我们实际项目中事件绑定都需要通过代码来写,这样便于管理(+=,-=),所以这里不使用EventTrigger这种办法,而是自定义事件监听类UIEventListener
在这里插入图片描述

3. UIWindow

using FrameWorkStudy.Event;
using FrameWorkStudy.Utils;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace FrameWorkStudy.UI
{
    public class UIWindow : MonoBehaviour
    {
        private CanvasGroup canvasGroup;

		/// <summary>
        /// 对同一节点缓存UI事件
        /// </summary>
        private Dictionary<string, UIEventListener> evtListenerDics = new Dictionary<string, UIEventListener>();

        private void Awake()
        {
            canvasGroup = GetComponent<CanvasGroup>();
        }

        public void SetVisible(bool state, int delay = 0)
        {
            StartCoroutine(SetVisibleDelay(state, delay));
        }

        public IEnumerator SetVisibleDelay(bool state, int delay)
        {
            yield return new WaitForSeconds(delay);
            // Unity官方不建议使用SetActive(false)隐藏, 建议通过修改canvasGroup的alpha值来显隐UI
            // 当然,如果您的项目没有这个要求,使用SetActive(...)来显隐UI也无伤大雅
            canvasGroup.alpha = state ? 1 : 0;
        }

        public UIEventListener GetUIEventListener(string childName)
        {
            if (!evtListenerDics.ContainsKey(childName))
            {
                var tf = transform.FindChildByName(childName);
                var uiEvent = UIEventListener.GetEventListener(tf);
                evtListenerDics.Add(childName, uiEvent);
            }
            return evtListenerDics[childName];
        }
    }
}

4. UIMgr

MonoSingleton是一个单例脚本,详情见上一小记【C#】Unity单例脚本

using FrameWorkStudy.MonoSingleton;
using FrameWorkStudy.UI;
using System.Collections.Generic;
using UnityEditor.PackageManager.UI;

namespace FrameWorkStudy.Mgr
{
    public class UIMgr : MonoSingleton<UIMgr>
    {
        private Dictionary<string, UIWindow> uiWindowDics;

        public override void Init()
        {
            base.Init();
            uiWindowDics = new Dictionary<string, UIWindow>();
            var uiWindows = FindObjectsOfType<UIWindow>();
            foreach (var uiWindow in uiWindows)
            {
                uiWindow.SetVisible(false);
                AddUIWindow(uiWindow);
            }
        }

        public void AddUIWindow(UIWindow window)
        {
            uiWindowDics.Add(window.GetType().Name, window);
        }

        public UIWindow GetWindow<T>()
        {
            string key = typeof(T).Name;
            return uiWindowDics.ContainsKey(key) ? uiWindowDics[key] : null;
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值