* 作者:闪电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()
{
}
}
}