UI忽略隐藏的节点,直接选中图片或文字

unity在project中点击某个节点时,会点到那些隐藏的节点,但是我们一般只是想获取能看到的那个,每次都要点半天才能找到,很麻烦。因此搞了这个工具,直接忽略隐藏节点获取鼠标点击位置的物体,方便多了。

使用方法:运行时在game窗口按下shift+alt+Q(不用打开窗口),可获取到鼠标点击会点到的物体。

如果打开了工具窗口,可以看到所有物体。窗口有两个选项【忽略隐藏的物体】【忽略raycast=false的物体】,作用就是名字,不多赘述了。

【当前相应事件的物体】就是点击会触发那个组件。

下面的列表指出所有可被点击的物体。

如果不忽略raycast能点到图片等等。

UI忽略隐藏的节点,直接选中图片或文字_第1张图片

 

using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class GetAllClickGameObjectWindow : EditorWindow
{
    private string helpStr =
@"按下shitf+alt+q,会获取当前鼠标下的所有UI物体。
请在运行模式下使用。
请在Game窗口中使用。";


    public bool ignoreHide = true;              //忽略隐藏的物体
    public bool ignoreRaycast = false;          //忽略raycast target=false的物体

    private GameObject currentSelect = null;    //当前鼠标可点击到的物体
    private GameObject currentClick = null;     //当前相应点击事件的物体
    private List gos                //在鼠标下所有物体
        = new List();
    private Vector2 scrolPos;


    private void OnGUI()
    {
        GUILayout.BeginHorizontal();
        if (GUILayout.Button("打开文档"))
        {
            EditorGUILayout.HelpBox(helpStr, MessageType.Info);
            //这里是项目文档链接,不放出来了
            Help.BrowseURL("https://www.baidu.com/");
        }
        GUILayout.EndHorizontal();
        ignoreHide = EditorGUILayout.Toggle("忽略隐藏的物体", ignoreHide);
        ignoreRaycast = EditorGUILayout.Toggle("忽略raycast=false的物体", ignoreRaycast);
        EditorGUILayout.ObjectField("当前直接点击的物体", currentSelect, typeof(GameObject), false);
        EditorGUILayout.ObjectField("当前相应事件的物体", currentClick, typeof(GameObject), false);
        GUILayout.Space(20);

        GUILayout.Label("以下为所有物体");
        scrolPos = GUILayout.BeginScrollView(scrolPos);
        for (int i = 0; i < gos.Count; i++)
        {
            EditorGUILayout.ObjectField(gos[i], typeof(GameObject), false);
        }
        GUILayout.EndScrollView();
    }

    public void Refresh()
    {
        MyGetPointOverUI();
        currentSelect = FindFirstRaycast(gos);
        currentClick = ExecuteEvents.GetEventHandler(currentSelect);
        Repaint();
    }

    public void MyGetPointOverUI()
    {
        gos = GetPointOverUI(ignoreHide, ignoreRaycast);
    }

    private GameObject FindFirstRaycast(List gos)
    {
        if (gos == null || gos.Count < 1) return null;
        return gos[0];
    }

    [MenuItem("Tools/UI节点选择工具")]
    public static void GetWindow()
    {
        var window = GetWindow(typeof(GetAllClickGameObjectWindow)) as GetAllClickGameObjectWindow;
        window.titleContent = new GUIContent("UI节点选择工具");
        window.Show();
    }

    private static double lastQuickSelectTime = 0;
    private static double quickSelectGap = 0.2f;
    //不打开窗口直接选中
    [MenuItem("Tools/用UI节点选择工具,这个没用 #&q")]
    public static void QuickSelect()
    {
        GetAllClickGameObjectWindow window = null;
        if (HasOpenInstances())
        {
            window = EditorWindow.GetWindow("UI节点选择工具", false);
        }
        bool ignoreHide = true, ignoreRaycast = false;
        if (window != null)
        {
            ignoreHide = window.ignoreHide;
            ignoreRaycast = window.ignoreRaycast;
        }

        if (Time.realtimeSinceStartup - lastQuickSelectTime < quickSelectGap)
            return;
        lastQuickSelectTime = Time.realtimeSinceStartup;

        var result = GetPointOverUI(ignoreHide, ignoreRaycast);

        var index = result.FindIndex(p => p?.gameObject == Selection.activeGameObject);
        index = (index + 1) % result.Count;
        if (0 <= index && index < result.Count)
        {
            Selection.activeGameObject = result[index].gameObject;
        }
        if (window != null) window.Refresh();
    }

    public static List GetPointOverUI(bool ignoreHide, bool ignoreRaycast)
    {
        Canvas[] canvasArray = FindObjectsOfType();
        List result = new List();
        for (int i = 0; i < canvasArray.Length; i++)
        {
            var canvas = canvasArray[i];
            Graphic[] graphics = canvas.GetComponentsInChildren(!ignoreHide);
            graphics.ToList().ForEach(p =>
            {
                //Debug.Log(p);
                if (ignoreRaycast && !p.raycastTarget) return;

                var pos = Input.mousePosition;
                Vector3[] ans = new Vector3[4];
                p.rectTransform.GetWorldCorners(ans);
                Vector3 min = ans[0], max = ans[2];

                if (canvas.renderMode == RenderMode.ScreenSpaceCamera)
                {
                    min = canvas.worldCamera.WorldToScreenPoint(min);
                    max = canvas.worldCamera.WorldToScreenPoint(max);
                }
                if (min.x <= pos.x && pos.x <= max.x && min.y <= pos.y && pos.y <= max.y)
                {
                    result.Add(p);
                }
            });
        }
        if (result.Count <= 0) return null;
        result.Sort((g1, g2) => g2.depth.CompareTo(g1.depth));
        return result.Select(p => p.gameObject).ToList();
    }
}

你可能感兴趣的:(unity,c#,unity,UGUI)