SDHK_Tool.Component.SC_TouchEvent_RayCast 触摸事件穿透器

 

* 作者:闪电Y黑客

* 日期: 2019.7.24

* 功能:将触摸事件变的可穿透

* 注:该组件要保持在所有ui的最上层

 

using System.Collections.Generic;
using System.Linq;
using SDHK_Tool.Static;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;


/*
 * 作者:闪电Y黑客
 * 
 * 日期: 2019.7.24
 * 
 * 功能:将触摸事件变的可穿透
 *
 * 注:该组件要保持在所有ui的最上层
 *
 */

namespace SDHK_Tool.Component
{

    /// <summary>
    /// 触摸事件穿透器:将触摸事件穿透所有UI
    /// </summary>
    public class SC_TouchEvent_RayCast : MonoBehaviour, IDragHandler, IPointerDownHandler, IPointerUpHandler
    {

        public static SC_TouchEvent_RayCast _instance;//单例


        /// <summary>
        /// 应用画布
        /// </summary>
        [Tooltip("应用画布")]
        public GraphicRaycaster canvas;//作用画布

        /// <summary>
        /// 拦截标签
        /// </summary>
        [Tooltip("拦截标签")]
        public string InterceptTag = "";//拦截标签

        /// <summary>
        /// 忽略层
        /// </summary>
        [Tooltip("忽略层")]
        public string[] IgnoreLayer;//忽略层




        /// <summary>
        /// 点击获取的UI集合字典
        /// </summary>
        public Dictionary<int, List<RaycastResult>> TouchRayDownLists;//点击集合

        /// <summary>
        /// 停留获取的UI集合字典
        /// </summary>
        public Dictionary<int, List<RaycastResult>> TouchRayEnterLists;//停留集合

        private Image Image;

        private void Awake()
        {
            _instance = this;//单例
        }

        // Use this for initialization
        void Start()
        {
            TouchRayDownLists = new Dictionary<int, List<RaycastResult>>();
            TouchRayEnterLists = new Dictionary<int, List<RaycastResult>>();

            Image //必须要有图片
            = (GetComponent<Image>() == null)
            ? gameObject.AddComponent<Image>()
            : GetComponent<Image>()
            ;

            Image.color = new Color(1, 1, 1, 0);//颜色透明化

        }

        public bool If_IgnoreLayer(RaycastResult UI)//判断忽略层
        {
            for (int i = 0; i < IgnoreLayer.Length; i++)//触摸事件穿透传递
            {
                if (UI.gameObject.layer == LayerMask.NameToLayer(IgnoreLayer[i])) return false;
            }
            return true;
        }


        public void OnPointerDown(PointerEventData eventData)//按下事件
        {
            List<RaycastResult> UI_List = new List<RaycastResult>();//提取物体列表
            foreach (var UIs in SS_Ray.UIRayCast(canvas, eventData.position))
            {
                if (If_IgnoreLayer(UIs))
                {
                    UI_List.Add(UIs);
                    if (UIs.gameObject.tag == InterceptTag) break;
                }
            }

            TouchRayDownLists.Add(eventData.pointerId, UI_List);    //添加物体列表到字典
            TouchRayEnterLists.Add(eventData.pointerId, UI_List);

            for (int i = 1; i < UI_List.Count; i++)//触摸事件穿透传递
            {
                //触摸事件通知:按下,停留,开始拖拽
                ExecuteEvents.Execute(UI_List[i].gameObject, eventData, ExecuteEvents.pointerDownHandler);
                ExecuteEvents.Execute(UI_List[i].gameObject, eventData, ExecuteEvents.pointerEnterHandler);
                ExecuteEvents.Execute(UI_List[i].gameObject, eventData, ExecuteEvents.beginDragHandler);
            }
        }

        public void OnPointerUp(PointerEventData eventData)//抬起事件
        {
            //抬起事件
            for (int i = 1; i < TouchRayDownLists[eventData.pointerId].Count; i++)//触摸事件穿透传递UP
            {
                if (TouchRayDownLists[eventData.pointerId][i].gameObject != null)
                {
                    //触摸事件通知:停止拖拽,抬起
                    ExecuteEvents.Execute(TouchRayDownLists[eventData.pointerId][i].gameObject, eventData, ExecuteEvents.endDragHandler);//触摸事件传递
                    ExecuteEvents.Execute(TouchRayDownLists[eventData.pointerId][i].gameObject, eventData, ExecuteEvents.pointerUpHandler);//触摸事件传递
                }
            }

            //点击事件
            List<RaycastResult> UI_List = new List<RaycastResult>();//提取物体列表
            foreach (var UIs in SS_Ray.UIRayCast(canvas, eventData.position))
            {
                if (If_IgnoreLayer(UIs))
                {
                    UI_List.Add(UIs);
                    if (UIs.gameObject.tag == InterceptTag) break;
                }
            }

            List<RaycastResult> Click_List = TouchRayDownLists[eventData.pointerId].Intersect(UI_List).ToList();


            for (int i = 1; i < Click_List.Count; i++)
            {
                if (Click_List[i].gameObject != null)
                {
                    //触摸事件通知:点击
                    ExecuteEvents.Execute(Click_List[i].gameObject, eventData, ExecuteEvents.pointerClickHandler);//触摸事件传递
                }

            }

            TouchRayDownLists.Remove(eventData.pointerId);  //去除物体列表


            //Exit
            for (int i = 1; i < TouchRayEnterLists[eventData.pointerId].Count; i++)//触摸事件穿透传递
            {
                if (TouchRayEnterLists[eventData.pointerId][i].gameObject != null)
                {
                    //触摸事件通知:离开
                    ExecuteEvents.Execute(TouchRayEnterLists[eventData.pointerId][i].gameObject, eventData, ExecuteEvents.pointerExitHandler);//触摸事件传递
                }
            }

            TouchRayEnterLists.Remove(eventData.pointerId);  //去除物体列表
        }

        public void OnDrag(PointerEventData eventData)//拖拽事件
        {
            //Drag
            for (int i = 1; i < TouchRayDownLists[eventData.pointerId].Count; i++)//触摸事件穿透传递
            {

                if (TouchRayDownLists[eventData.pointerId][i].gameObject != null)
                {
                    //触摸事件通知:拖拽
                    ExecuteEvents.Execute(TouchRayDownLists[eventData.pointerId][i].gameObject, eventData, ExecuteEvents.dragHandler);//触摸事件传递
                    if (TouchRayDownLists[eventData.pointerId][i].gameObject.tag == InterceptTag) break;
                }


            }

            //Enter,Exit
            List<RaycastResult> UI_List = new List<RaycastResult>();//提取物体列表
            foreach (var UIs in SS_Ray.UIRayCast(canvas, eventData.position))
            {
                if (If_IgnoreLayer(UIs))
                {
                    UI_List.Add(UIs);
                    if (UIs.gameObject.tag == InterceptTag) break;
                }
            }

            List<RaycastResult> Enter_List = UI_List.Except(TouchRayEnterLists[eventData.pointerId]).ToList();
            List<RaycastResult> Exit_List = TouchRayEnterLists[eventData.pointerId].Except(UI_List).ToList();

            for (int i = 0; i < Enter_List.Count; i++)
            {
                if (Enter_List[i].gameObject != null)
                {
                    //触摸事件通知:停留
                    ExecuteEvents.Execute(Enter_List[i].gameObject, eventData, ExecuteEvents.pointerEnterHandler);//触摸事件传递
                }

            }

            for (int i = 0; i < Exit_List.Count; i++)
            {
                if (Exit_List[i].gameObject != null)
                {
                    //触摸事件通知:离开
                    ExecuteEvents.Execute(Exit_List[i].gameObject, eventData, ExecuteEvents.pointerExitHandler);//触摸事件传递
                }

            }
            TouchRayEnterLists[eventData.pointerId] = UI_List;
        }

        /// <summary>
        /// 刷新触摸点
        /// </summary>
        /// <param name="EventData">触摸点</param>
        public void TouchRefresh(PointerEventData EventData)
        {
            OnPointerUp(EventData);
            OnPointerDown(EventData);
        }


        // Update is called once per frame
        void Update()
        {

        }
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值