Unity UGUI优化之RaycastTarget

发表于2018-10-25
评论0 5.3k浏览
UGUI默认会打开一些组件的RaycastTarget属性。下面就来看看RaycastTarget的优化小技巧。

1、RaycastTarget的检测
using UnityEngine;
using UnityEngine.UI;
public class DrawRaycastTarget : MonoBehaviour {
    Vector3[] worldCorners = new Vector3[4];
    private void OnDrawGizmos()
    {
        foreach (MaskableGraphic maskableGraphic in FindObjectsOfType<MaskableGraphic>())
        {
            if (maskableGraphic.raycastTarget)
            {
                RectTransform rectTransform = maskableGraphic.transform as RectTransform;
                rectTransform.GetWorldCorners(worldCorners);
                Gizmos.color = Color.red;
                for (int i = 0; i < 4; i++)
                {
                    Gizmos.DrawLine(worldCorners[i], worldCorners[(i + 1) % 4]);
                }
            }
        }
    }
}

效果如下:

2、批量修改RaycastTarget
using UnityEditor;
using UnityEngine.UI;
using UnityEngine;
public class RaycastTargetChecker : EditorWindow
{
    private MaskableGraphic[] graphics;
    private bool hideUnchecked = false;
    private bool showBorders = true;
    private Color borderColor = Color.blue;
    private Vector2 scrollPosition = Vector2.zero;
    private static RaycastTargetChecker instance = null;
    [MenuItem("Tools/RaycastTarget Checker")]
    private static void Open()
    {
        instance = instance ?? EditorWindow.GetWindow<RaycastTargetChecker>("RaycastTargets");
        instance.Show();
    }
    void OnEnable()
    {
        instance = this;
    }
    void OnDisable()
    {
        instance = null;
    }
    void OnGUI()
    {
        using (EditorGUILayout.HorizontalScope horizontalScope = new EditorGUILayout.HorizontalScope())
        {
            showBorders = EditorGUILayout.Toggle("Show Gizmos", showBorders, GUILayout.Width(200.0f));
            borderColor = EditorGUILayout.ColorField(borderColor);
        }
        hideUnchecked = EditorGUILayout.Toggle("Hide Unchecked", hideUnchecked);
        GUILayout.Space(12.0f);
        Rect rect = GUILayoutUtility.GetLastRect();
        GUI.color = new Color(0.0f, 0.0f, 0.0f, 0.25f);
        GUI.DrawTexture(new Rect(0.0f, rect.yMin + 6.0f, Screen.width, 4.0f), EditorGUIUtility.whiteTexture);
        GUI.DrawTexture(new Rect(0.0f, rect.yMin + 6.0f, Screen.width, 1.0f), EditorGUIUtility.whiteTexture);
        GUI.DrawTexture(new Rect(0.0f, rect.yMin + 9.0f, Screen.width, 1.0f), EditorGUIUtility.whiteTexture);
        GUI.color = Color.white;
        graphics = GameObject.FindObjectsOfType<MaskableGraphic>();
        using (GUILayout.ScrollViewScope scrollViewScope = new GUILayout.ScrollViewScope(scrollPosition))
        {
            scrollPosition = scrollViewScope.scrollPosition;
            for (int i = 0; i < graphics.Length; i++)
            {
                MaskableGraphic graphic = graphics[i];
                if (hideUnchecked == false || graphic.raycastTarget == true)
                {
                    DrawElement(graphic);
                }
            }
        }
        foreach (var item in graphics)
        {
            EditorUtility.SetDirty(item);
        }
        Repaint();
    }
    private void DrawElement(MaskableGraphic graphic)
    {
        using (EditorGUILayout.HorizontalScope horizontalScope = new EditorGUILayout.HorizontalScope())
        {
            Undo.RecordObject(graphic, "Modify RaycastTarget");
            graphic.raycastTarget = EditorGUILayout.Toggle(graphic.raycastTarget, GUILayout.Width(20));
            EditorGUI.BeginDisabledGroup(true);
            EditorGUILayout.ObjectField(graphic, typeof(MaskableGraphic), true);
            EditorGUI.EndDisabledGroup();
        }
    }
    [DrawGizmo(GizmoType.Selected | GizmoType.NonSelected)]
    private static void DrawGizmos(MaskableGraphic source, GizmoType gizmoType)
    {
        if (instance != null && instance.showBorders == true && source.raycastTarget == true)
        {
            Vector3[] corners = new Vector3[4];
            source.rectTransform.GetWorldCorners(corners);
            Gizmos.color = instance.borderColor;
            for (int i = 0; i < 4; i++)
            {
                Gizmos.DrawLine(corners[i], corners[(i + 1) % 4]);
            }
            if (Selection.activeGameObject == source.gameObject)
            {
                Gizmos.DrawLine(corners[0], corners[2]);
                Gizmos.DrawLine(corners[1], corners[3]);
            }
        }
        SceneView.RepaintAll();
    }
}

效果如下:

3、创建UI控件时自动取消RaycastTarget
using UnityEngine;
using UnityEditor;
using UnityEngine.UI;
public class CancelRaycastTarget {
    [MenuItem("GameObject/UI/Image")]
    static void CreatImage()
    {
        if (Selection.activeTransform)
        {
            if (Selection.activeTransform.GetComponentInParent<Canvas>())
            {
                GameObject go = new GameObject("Image", typeof(Image));
                go.GetComponent<Image>().raycastTarget = false;
                go.transform.SetParent(Selection.activeTransform);
            }
        }
    }
    [MenuItem("GameObject/UI/Text")]
    static void CreatText()
    {
        if (Selection.activeTransform)
        {
            if (Selection.activeTransform.GetComponentInParent<Canvas>())
            {
                GameObject go = new GameObject("Text", typeof(Text));  
                go.GetComponent<Text>().raycastTarget = false;  
                go.transform.SetParent(Selection.activeTransform);
            }
        }
    }
    [MenuItem("GameObject/UI/Raw Image")]
    static void CreatRawImage()
    {
        if (Selection.activeTransform)
        {
            if (Selection.activeTransform.GetComponentInParent<Canvas>())
            { 
                GameObject go = new GameObject("RawImage", typeof(RawImage)); 
                go.GetComponent<RawImage>().raycastTarget = false;
                go.transform.SetParent(Selection.activeTransform);
            }
        }
    }
}

如社区发表内容存在侵权行为,您可以点击这里查看侵权投诉指引