1.給3D攝像機掛一個Physics Raycaster組件。Event Mask過濾掉UI.
2.用unity自帶的Event Trigger 或者 http://www.xuanyusong.com/archives/3325 就可以對UI 或者 3D模型進行點擊事件的監聽了
3.OK 當UI與模型相互疊加的時候,優先響應UI,並且響應最前面的UI.
4.如下圖所示,前面是UI後面是3D模型,被擋住的模型或者UI是不會被響應的。
假如想把點擊的事件透下去,讓所有的UI或者模型都能正確的響應事件,怎麼辦呢?
代碼: 把這段腳本掛在最前面的UI上。 然後當接收到點擊事件後,調用PassEvent把當前的事件透下去。由於UGUI的事件有很多種,比如點擊 、擡起、拖動、落下、第二個參數就是ExecuteEvents.Handler 把對應的Handler傳進去就行了。
using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using System.Collections.Generic;
public class Test : MonoBehaviour,IPointerClickHandler ,IPointerDownHandler,IPointerUpHandler
{
//監聽按下
public void OnPointerDown(PointerEventData eventData)
{
PassEvent(eventData,ExecuteEvents.pointerDownHandler);
}
//監聽擡起
public void OnPointerUp(PointerEventData eventData)
{
PassEvent(eventData,ExecuteEvents.pointerUpHandler);
}
//監聽點擊
public void OnPointerClick(PointerEventData eventData)
{
PassEvent(eventData,ExecuteEvents.submitHandler);
PassEvent(eventData,ExecuteEvents.pointerClickHandler);
}
//把事件透下去
public void PassEvent<T>(PointerEventData data,ExecuteEvents.EventFunction<T> function)
where T : IEventSystemHandler
{
List<RaycastResult> results = new List<RaycastResult>();
EventSystem.current.RaycastAll(data, results);
GameObject current = data.pointerCurrentRaycast.gameObject ;
for(int i =0; i< results.Count;i++)
{
if(current!= results[i].gameObject)
{
ExecuteEvents.Execute(results[i].gameObject, data,function);
//RaycastAll後ugui會自己排序,如果你只想響應透下去的最近的一個響應,這裏ExecuteEvents.Execute後直接break就行。
}
}
}
}
這樣UI下面那些對應接收點擊事件的地方都可以響應到了。。如下圖所示,我點擊在前面的UI後面的消息也能響應到了。
- 本文固定鏈接: http://www.xuanyusong.com/archives/4241
- 轉載請註明: 雨鬆MOMO 2016年09月05日 於 雨鬆MOMO程序研究院 發表