Ⅰ, A和B是兄弟ide
Ⅱ, C是A的孩子测试
Ⅰ, 代码spa
A , B , C 分别挂载A.cs , B.cs , C.cs , 分别以下设计
A.cs 代码以下code
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 代码以下blog
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.csit
1, 点击C的时候A会触发事件io
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); } } } }
1, 脚本
using UnityEngine; using UnityEngine.UI; public class ImageExtends : Image { override public bool IsRaycastLocationValid(Vector2 sp, Camera eventCamera) { return false;//不拦截, (本身也不会触发Event) } }
2, 将脚本挂载到B的GameObject上
1, A.cs 继承 ICanvasRaycastFilter
2, 重写 IsRaycastLocationValid() 方法
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; } }
当 IsFocus 为false 时, A,C不触发Event