GUI.BeginClip裁剪使用

 

public class EditorClipDemoWnd : EditorWindow
{
    [MenuItem("Demos/EditorClipDemoWnd")]
    static void ShowWindow()
    {
        var window = GetWindow<EditorClipDemoWnd>();
        window.titleContent = new GUIContent("EditorClipDemoWnd");
        window.Show();
    }
    
    private string[] m_ToolbarNames = { "scrollOff.y", "renderOff.y", "clip.y" };
    private int m_ToolbarIndex = 0;
    
    ///裁剪区域
    private Rect m_ViewportRect;
    private float m_ContentHeight;
    ///GUI.BeginClip的scrollOffset参数
    private Vector2 m_ScrollOffset;
    /// GUI.BeginClip的renderOffset参数
    private Vector2 m_RenderOffset;
    /// GUI.BeginClip的resetOffset参数
    public bool m_ResetOffset;
    
    private void OnEnable()
    {
        m_ViewportRect = new Rect(0, 0, 200, 60);
    }
    
    private void OnGUI()
    {
        EditorGUI.DrawRect(m_ViewportRect, Color.gray); //绘制出裁剪区域
        
        GUI.BeginClip(m_ViewportRect, m_ScrollOffset, m_RenderOffset, m_ResetOffset);
        {
            //内容超出视口将被裁减掉
            EditorGUILayout.LabelField("aaaaaaa");
            EditorGUILayout.LabelField("bbbbbbb");
            EditorGUILayout.LabelField("ccccccc");
            EditorGUILayout.LabelField("ddddddd");
            EditorGUILayout.LabelField("fffffff");
        }
        GUI.EndClip();
        
        if (Event.current.type == EventType.Repaint)
        {
            var rect = GUILayoutUtility.GetLastRect();
            m_ContentHeight = rect.yMax;
        }
        
        //滚动条放在裁剪区域右侧
        float scrollBarMaxPos = Mathf.Max(0, m_ContentHeight - m_ViewportRect.height); //内容超出的部分即为可滚动距离
        float scrollBarPos = Mathf.Clamp(-m_ScrollOffset.y, 0, scrollBarMaxPos);
        Rect scrollBarRect = new Rect(m_ViewportRect.xMax, m_ViewportRect.y, 13, m_ViewportRect.height);
        scrollBarPos = GUI.VerticalScrollbar(scrollBarRect, scrollBarPos, m_ViewportRect.height, 0,
            Mathf.Max(m_ViewportRect.height, m_ContentHeight));
        m_ScrollOffset.y = -scrollBarPos;

        EditorGUILayout.Space();
        m_ToolbarIndex = GUILayout.Toolbar(m_ToolbarIndex, m_ToolbarNames);
        m_ResetOffset = EditorGUILayout.ToggleLeft("resetOffset", m_ResetOffset);
        if (GUILayout.Button("ResetAll"))
        {
            m_ViewportRect.position = Vector2.zero;
            m_ScrollOffset = Vector2.zero;
            m_RenderOffset = Vector2.zero;
            m_ResetOffset = false;
        }

        if (Event.current.isScrollWheel)
        {
            var delta = Event.current.delta; //向下滚动滚轮, delay.y>0
            if (0 == m_ToolbarIndex)
            {
                m_ScrollOffset.y -= delta.y; //scrollOffset.y<0时ui往上移动
                Debug.Log($"delta:{delta.y}, scrollOffset:{m_ScrollOffset.y}");
            }
            else if (1 == m_ToolbarIndex)
            {
                m_RenderOffset.y -= delta.y; //renderOffset.y<0时ui往下移动
                Debug.Log($"delta:{delta.y}, renderOffset:{m_RenderOffset.y}");
            }
            else if (2 == m_ToolbarIndex)
            {
                m_ViewportRect.y -= delta.y; //viewportRect.y<0时ui往上移动
                Debug.Log($"delta:{delta.y}, viewport:{m_ViewportRect.y}");
            }

            Repaint();
        }
    }
    
}

 

仅scrollOffset.y变小:裁剪区域不变, y<0 ui内容向上移动

 仅renderOffset.y变小:裁剪区域大小不变, y<0 viewport向下移动

仅viewportRect.y变大:裁剪区域大小不变,y>0 viewport向下移动

 所以:

GUI.BeginClip(new Rect(0, 0, 66, 17), Vector2.zero, new Vector2(0, -10), false);
GUI.BeginClip(new Rect(0, 10, 66, 17), Vector2.zero, new Vector2(0, 0), false);

可以得到一样的viewport向下移动10像素的效果

 

先viewportRect.y变大,再renderOffset变小,再scrollOffset变小

 

resetOffset为true时,renderOffset将相对于窗口标题的左上角(而不是裁剪区域的左上角),同时scrollOffset将不起作用

 

参考:
 
 
 
posted @ 2024-11-09 00:02  yanghui01  阅读(1)  评论(0编辑  收藏  举报