Unity3D研究院之UI完整透下事件(一百二十二)——雨松MOMO
简介
当UI打开一个小的提示tip的时候,常见的需求是点击其他任意地方就关闭tip,这个功能很常见,空白出响应点击,监听到就关闭tip,这里会发现一个问题,我们并不能响应tip面板底下的其他按钮,这样玩家在操作的时候就需要先关掉tip,然后再点一下按钮,这往往不是策划想要的,所以我们需要在点击空白处关闭的时候同时响应底下的按钮,这个时候就需要点击穿透事件。
代码
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
namespace ZHEngine.UI
{
public sealed class UTouchPass : MonoBehaviour, IPointerClickHandler,
IMoveHandler,IPointerDownHandler, IPointerUpHandler,IPointerEnterHandler,ISelectHandler, IDeselectHandler
, ISubmitHandler, IInitializePotentialDragHandler, IBeginDragHandler, IEndDragHandler, IDragHandler, IScrollHandler
{
private GameObject CacheGameObject;
private readonly List<RaycastResult> result = new List<RaycastResult>();
public void OnPointerClick(PointerEventData eventData)
{
PassEvent(eventData, ExecuteEvents.pointerClickHandler);
}
public void OnPointerDown(PointerEventData eventData)
{
PassEvent(eventData, ExecuteEvents.pointerDownHandler);
if (Input.GetButtonDown("Submit"))
ExecuteEvents.Execute(eventData.pointerCurrentRaycast.gameObject, eventData, ExecuteEvents.submitHandler);
}
public void OnPointerUp(PointerEventData eventData)
{
PassEvent(eventData, ExecuteEvents.pointerUpHandler);
}
public void OnPointerEnter(PointerEventData eventData)
{
PassEvent(eventData, ExecuteEvents.pointerEnterHandler);
}
public void OnSelect(BaseEventData eventData)
{
PassEvent(eventData, ExecuteEvents.selectHandler);
}
public void OnDeselect(BaseEventData eventData)
{
PassEvent(eventData, ExecuteEvents.deselectHandler);
}
public void OnSubmit(BaseEventData eventData)
{
PassEvent(eventData, ExecuteEvents.submitHandler);
}
public void OnMove(AxisEventData eventData)
{
PassEvent(eventData, ExecuteEvents.moveHandler);
}
public void OnInitializePotentialDrag(PointerEventData eventData)
{
CacheGameObject = PassEvent(eventData, ExecuteEvents.initializePotentialDrag);
}
public void OnBeginDrag(PointerEventData eventData)
{
PassEvent(eventData, ExecuteEvents.beginDragHandler);
}
public void OnDrag(PointerEventData eventData)
{
ExecuteEvents.Execute(CacheGameObject, eventData, ExecuteEvents.dragHandler);
}
public void OnEndDrag(PointerEventData eventData)
{
ExecuteEvents.Execute(CacheGameObject, eventData, ExecuteEvents.endDragHandler);
CacheGameObject = null;
}
public void OnScroll(PointerEventData eventData)
{
ExecuteEvents.Execute(CacheGameObject, eventData, ExecuteEvents.scrollHandler);
}
private GameObject PassEvent<T>(BaseEventData data, ExecuteEvents.EventFunction<T> function) where T : IEventSystemHandler
{
if (data is PointerEventData eventData)
{
var pointerGo = eventData.pointerCurrentRaycast.gameObject
? eventData.pointerCurrentRaycast.gameObject
: eventData.pointerDrag;
EventSystem.current.RaycastAll(eventData, result);
foreach (var item in result)
{
var go = item.gameObject;
if (go != null && go != pointerGo)
{
var executeGo = ExecuteEvents.GetEventHandler<T>(go);
if (executeGo)
{
if (executeGo.TryGetComponent<UTouchPass>(out var __))
return null;
ExecuteEvents.Execute(executeGo, data, function);
return executeGo;
}
else
{
if(go.TryGetComponent<UnityEngine.UI.Graphic>(out var com))
{
if (com.raycastTarget) return null;
}
}
}
}
}
return null;
}
}
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 841774407@qq.com