You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity EditorWindow滚动条过窄、数组标题随内容滚动问题求解

滚动条初始问题

问题解决方法

两个核心问题的修复逻辑如下:

  • 固定数组父标题:不要把整个数组的PropertyField放进滚动视图,先单独绘制数组的父标题(含折叠、数组大小调整控件),只把数组的元素列表放到滚动区域内,滚动时就只会移动元素,标题保持固定
  • 滚动视图宽度异常:之前宽度设置失效是因为外层套了无参数的BeginHorizontal,水平布局会默认按内容最小宽度适配,把多余的水平布局去掉,滚动视图宽度用GUILayout.ExpandWidth(true)配合窗口宽度适配,就不会出现设置宽度反而偏移的问题。

修改后滚动效果

修正后完整代码

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;

public class RenameSelected : EditorWindow
{
    private static readonly Vector2Int size = new Vector2Int(500, 500);
    private string childrenPrefix;
    private int startIndex;
    private SerializedObject _serializedObject;
    public GameObject[] objects;
    private Vector2 scrollPos;
    private SerializedProperty objectsProperty;

    [MenuItem("GameObject/Rename Selected")]
    public static void ShowWindow()
    {
        EditorWindow window = GetWindow<RenameSelected>();
        window.minSize = size;
        window.maxSize = size;
    }

    private void OnSelectionChange()
    {
        objects = Selection.gameObjects;
    }

    private void OnEnable()
    {
        _serializedObject = new SerializedObject(this);
        objectsProperty = _serializedObject.FindProperty("objects");
        objects = Selection.gameObjects;
    }

    private void OnGUI()
    {
        childrenPrefix = EditorGUILayout.TextField("Children prefix", childrenPrefix);
        startIndex = EditorGUILayout.IntField("Start index", startIndex);

        _serializedObject.Update();

        // 单独绘制固定的数组父标题,支持折叠、数组大小修改
        EditorGUILayout.PropertyField(objectsProperty, new GUIContent("Objects"), false);
        
        // 只有数组展开的时候才绘制滚动区域和内部元素
        if (objectsProperty.isExpanded)
        {
            EditorGUI.indentLevel++;
            // 滚动区域设置固定高度,宽度自动适配窗口,不会偏移
            scrollPos = EditorGUILayout.BeginScrollView(scrollPos, GUILayout.Height(300), GUILayout.ExpandWidth(true));
            for (int i = 0; i < objectsProperty.arraySize; i++)
            {
                SerializedProperty element = objectsProperty.GetArrayElementAtIndex(i);
                EditorGUILayout.PropertyField(element, new GUIContent($"Object {i}"), true);
            }
            EditorGUILayout.EndScrollView();
            EditorGUI.indentLevel--;
        }

        _serializedObject.ApplyModifiedProperties();

        GUILayout.Space(10);
        if (GUILayout.Button("Rename children"))
        {
            for (int objectI = 0; objectI < objects.Length; objectI++)
            {
                Transform selectedObjectT = objects[objectI].transform;
                for (int childI = 0, i = startIndex; childI < selectedObjectT.childCount; childI++)
                {
                    selectedObjectT.GetChild(childI).name = $"{childrenPrefix}{i++}";
                }
            }
        }
    }
}

代码说明

  • 调用EditorGUILayout.PropertyField传includeChildren:false参数,只会绘制数组的父级标题栏,包含原生的折叠箭头、数组大小输入框、对象引用拖拽槽,和默认绘制的数组标题完全一致
  • 判断isExpanded状态,只有用户展开数组时才绘制内部的滚动列表,折叠时自动隐藏元素区域,符合Unity编辑器原生交互逻辑
  • 滚动视图去掉了多余的水平布局包裹,用GUILayout.ExpandWidth(true)让宽度自动撑满可用区域,不会出现之前设置宽度反而偏移的问题,滚动区域高度可以按需调整数值
  • 增加了EditorGUI.indentLevel的缩进调整,数组元素和父标题的层级缩进和原生Inspector保持一致
  • 补上了_serializedObject.ApplyModifiedProperties(),确保序列化数据修改能正确保存,不会出现数组拖拽赋值后刷新丢失的问题

内容的提问来源于stack exchange,提问作者Daniel Lip

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 09:36:24