在编辑器脚本中,如何在保留的矩形区域内使用GUILayout方法?

编程语言 2026-07-09

在一个编辑器脚本中,通过使用 GUILayoutUtility.GetRect 方法获取一个保留的矩形(这一步其实是由第三方传入的,因此我无法修改),然后需要在这个矩形内使用 GUILayout.* 方法绘制控件。我曾考虑使用 GUILayout.BeginArea 方法,但结果是内部控件不可见。如何解决这个问题?

[CustomEditor(typeof(Foo))]
public class TestAreaEditor : Editor
{
    public override void OnInspectorGUI()
    {
        var rect = GUILayoutUtility.GetRect(100f, 100f);
        GUI.Box(rect, "Box");
        UserDraw(rect);
    }

    public void UserDraw(Rect rect)
    {
        GUILayout.BeginArea(rect);
        GUILayout.Button("Button");
        GUILayout.EndArea();
    }
}

public class Foo : MonoBehaviour
{
}

预期:

预期

实际:

实际

解决方案

你通常不会这样做。

如果你采用一个修复 Rect,就使用来自 EditorGUI / GUI 的固定版本。以你为例,例如 GUI.Button

我可以通过在 Repaint 事件内约束该矩形来解决你的问题。这样后续的布局就不会把该区域挤压塌陷。

private Rect _rect;

public void UserDraw(Rect rect)
{
    if (Event.current.type == EventType.Repaint)
    {
        _rect = rect;
    }

    GUILayout.BeginArea(_rect);
    GUILayout.Button("Button");
    GUILayout.EndArea();
}

在此输入图片描述

不过这看起来仍然像是一种权宜之计。

特别是对于

我想用它来绘制它的目标对象列表

无论如何你都需要将其放入一个滚动区域以绕过高度限制,我还建议同时使用一个缩进——否则根级别的折叠控件把手会被该区域裁切掉。

private Rect _rect;
private Vector2 _scroll;

public void UserDraw(Rect rect)
{
    if (Event.current.type == EventType.Repaint)
    {
        _rect = rect;
    }

    GUILayout.BeginArea(_rect);
    using (var scroll =new EditorGUILayout.ScrollViewScope(_scroll,GUILayout.ExpandHeight(true)))
    {
        _scroll = scroll.scrollPosition;

        using (new EditorGUI.IndentLevelScope())
        {
            serializedObject.Update();
            EditorGUILayout.PropertyField(serializedObject.FindProperty("test"), true);
            serializedObject.ApplyModifiedProperties();
        }
    }
    GUILayout.EndArea();
}

在此输入图片描述

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章