可穿透按钮

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class PenetratableButton : Button
{
    List<RaycastResult> results = new List<RaycastResult>();
    [Header("向下穿几层")]
    public int depth = 1;
    private List<GameObject> gos = new List<GameObject>();
    public override void OnPointerDown(PointerEventData eventData)
    {
        gos.Clear();
        results.Clear();
        base.OnPointerDown(eventData);
        EventSystem.current.RaycastAll(eventData, results);
        GameObject current = eventData.pointerCurrentRaycast.gameObject;
        int _depth = 0;
        for (int i = 0; i < results.Count; i++)
        {
            if (results[i].gameObject == current)
            {
                _depth = results[i].depth;
                break;
            }
        }
        for (int i = 0; i < results.Count; i++)
        {
            if (results[i].gameObject != current && results[i].depth >= _depth - this.depth)
            {
                gos.Add(results[i].gameObject);
                ExecuteEvents.Execute(results[i].gameObject, eventData, ExecuteEvents.pointerDownHandler);
            }
        }
    }
    public override void OnPointerUp(PointerEventData eventData)
    {
        results.Clear();
        base.OnPointerUp(eventData);
        EventSystem.current.RaycastAll(eventData, results);
        GameObject current = eventData.pointerCurrentRaycast.gameObject;
        int _depth = 0;
        for (int i = 0; i < results.Count; i++)
        {
            if (results[i].gameObject == current)
            {
                _depth = results[i].depth;
                break;
            }
        }
        for (int i = 0; i < gos.Count; i++)
        {
            ExecuteEvents.Execute(gos[i].gameObject, eventData, ExecuteEvents.pointerUpHandler);
        }
    }
    public override void OnPointerClick(PointerEventData eventData)
    {
        results.Clear();
        base.OnPointerClick(eventData);
        EventSystem.current.RaycastAll(eventData, results);
        GameObject current = eventData.pointerCurrentRaycast.gameObject;
        int _depth = 0;
        for (int i = 0; i < results.Count; i++)
        {
            if (results[i].gameObject == current)
            {
                _depth = results[i].depth;
                break;
            }
        }
        for (int i = 0; i < results.Count; i++)
        {
            if (results[i].gameObject != current && results[i].depth >= _depth - this.depth)
            {
                ExecuteEvents.Execute(results[i].gameObject, eventData, ExecuteEvents.pointerClickHandler);
            }

        }
    }

}
using UnityEditor;

[CustomEditor(typeof(PenetratableButton))]
public class PenetratableButtonEditor : Editor
{
    private SerializedProperty property;
    private void OnEnable()
    {
        property = serializedObject.FindProperty("depth");
    }
    public override void OnInspectorGUI()
    {
        EditorGUILayout.PropertyField(property);
        {
            serializedObject.ApplyModifiedProperties();
        }
        base.OnInspectorGUI();

    }
}