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将不起作用
参考: