一 , Scene設計
Ⅰ, A和B是兄弟
Ⅱ, C是A的孩子

二, 測試一(穿透測試)
Ⅰ, 代碼
A , B , C 分别挂載A.cs , B.cs , C.cs , 分别如下
A.cs 代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class A : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("A click");
}
}
B.cs 代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class B : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("B click");
}
}
C.cs 代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class C : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("C click");
}
}
Ⅱ, 測試
A, 解除安裝 B 和 C的腳本 B.cs 和 C.cs
1, 點選C的時候A會觸發事件
2, 點選B的時候A不會觸發事件(兄弟攔截了)
B, 将B 和 C 的 腳本B.cs 和 C.cs重新挂載到B,C上
1, 點選C的時候A不會觸發事件(被C攔截了)
2, 和上面一樣點選B,A也不會觸發事件
三, 測試二(傳遞測試)
1, 特殊需求: 無論點選B或者C都會觸發下面的A
B.cs 代碼如下
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class B : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("B click");
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);
}
}
}
}
C.cs 代碼
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class C : MonoBehaviour, IPointerClickHandler
{
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("C click");
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);
}
}
}
}
四, 需求:B不需要Event, 但是要透過B可以觸發A的Event
1, 腳本
using UnityEngine;
using UnityEngine.UI;
public class ImageExtends : Image
{
override public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
return false;//不攔截, (自己也不會觸發Event)
}
}
2, 将腳本挂載到B的GameObject上
五, 需求: 關閉A及A的孩子的Event
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class A : MonoBehaviour, IPointerClickHandler, ICanvasRaycastFilter
{
[SerializeField]
private bool IsFocus = false;
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("A click");
}
public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera)
{
return IsFocus;
}
}