IEventSystemHandler を持つコンポーネントがオブジェクトに複数あった場合
どういった挙動になるのか気になったので
ボタンと下記コンポーネントを同じオブジェクトに追加して
どんなログが出るかを確認する
using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.UI; public class SampleMonoBehaviour : MonoBehaviour, IPointerDownHandler { [SerializeField] private Button _button; private void Awake() { _button.onClick.AddListener(() => Debug.LogWarning("Click")); } public void OnPointerDown(PointerEventData eventData) { Debug.LogWarning("Down"); } }
結果
同じオブジェクトに、同じ interface を持つコンポーネントがあってもどちらも呼ばれることが確認できた
コードを見てみる
EventSystems の伝播処理をしているクラスは下記で
uGUI/ExecuteEvents.cs at 135661e057d2a45f5b5b73ea48fb67a445816f61 · Unity-Technologies/uGUI · GitHub
実際にイベントを実行しているメソッドがこちら
/// <summary> /// Bubble the specified event on the game object, figuring out which object will actually receive the event. /// </summary> public static GameObject GetEventHandler<T>(GameObject root) where T : IEventSystemHandler { if (root == null) return null; Transform t = root.transform; while (t != null) { if (CanHandleEvent<T>(t.gameObject)) return t.gameObject; t = t.parent; } return null; }
Raycast がヒットしたオブジェクトから、対象の IEventSystemHandler が持つコンポーネントがあるかを確認して
なければ親を探すという作りになっている
対象の IEventSystemHandler を確認する際に GetComponents をしているため、そのオブジェクトが複数の IEventSystemHandler
をもっていてもすべて実行されるということでした