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

Unity Editor如何在GameObject字段右侧添加Toggle复选框

Unity 自定义编辑器:ObjectField 右侧紧邻 Toggle 实现方案

问题原因

  • 默认垂直布局下控件逐行渲染,直接顺序编写 Toggle 和 ObjectField 代码会导致两个控件上下排布,不符合同行要求
  • 水平布局下硬编码控件固定最小/最大宽度,会导致空间分配冲突:要么挤压 Toggle 导致文本显示不全,要么总宽度超出滚动视图触发多余横向滚动条
  • 原代码存在逻辑问题:循环内直接修改全局includeChildren变量,会导致所有行的复选框共用同一个状态,无法单独控制。

正确实现代码

前置变量修正

首先补充每个物体独立的勾选状态存储数组,替换循环内对全局变量的错误调用:

// 原有全局变量保留
public string childrenPrefix;
public int startIndex;
public bool includeChildren;
public Vector2 scrollPos;
public bool showPosition;
public GameObject[] objects;

// 新增:和物体数组等长,存储每一行单独的Toggle状态
public bool[] perObjectToggleFlags;

OnGUI 逻辑修正

核心是用水平布局包裹两个控件,ObjectField自适应占满剩余空间,Toggle用固定宽度保证文本完整显示:

public void OnGUI()
{
    GUILayout.Space(10);
    childrenPrefix = EditorGUILayout.TextField("Rename prefix", childrenPrefix);
    startIndex = EditorGUILayout.IntField("Start index", startIndex);
    includeChildren = EditorGUILayout.Toggle("Include Children", includeChildren);

    if (objects.Length == 0)
    {
        showPosition = false;
    }
    GUILayout.Space(20);
    EditorGUI.BeginChangeCheck();
    EditorGUILayout.GetControlRect(true, 16f, EditorStyles.foldout);
    Rect foldRect = GUILayoutUtility.GetLastRect();
    if (Event.current.type == EventType.MouseUp && foldRect.Contains(Event.current.mousePosition))
    {
        showPosition = !showPosition;
        GUI.changed = true;
        Event.current.Use();
    }

    showPosition = EditorGUI.Foldout(foldRect, showPosition, "Objects");
    GUILayout.Space(2);

    if (showPosition)
    {
        EditorGUI.indentLevel++;
        scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
        
        // 保证状态数组和物体数组长度匹配
        if (perObjectToggleFlags == null || perObjectToggleFlags.Length != objects.Length)
        {
            perObjectToggleFlags = new bool[objects.Length];
        }

        for (int i = 0; i < objects.Length; i++)
        {
            // 先设置ObjectField的标签宽度
            EditorGUIUtility.labelWidth = 50;
            EditorGUILayout.BeginHorizontal();
            
            // ObjectField自适应填充剩余空间,不设硬编码宽度
            objects[i] = (GameObject)EditorGUILayout.ObjectField(
                i.ToString(), 
                objects[i], 
                typeof(GameObject), 
                true,
                GUILayout.ExpandWidth(true)
            );
            
            // 临时调整标签宽度适配Toggle文本,给Toggle设固定宽度避免被挤压
            EditorGUIUtility.labelWidth = 95;
            perObjectToggleFlags[i] = EditorGUILayout.Toggle(
                "Include Children", 
                perObjectToggleFlags[i],
                GUILayout.Width(120f)
            );
            
            EditorGUILayout.EndHorizontal();
        }
        EditorGUILayout.EndScrollView();
        EditorGUI.indentLevel--;
    }
}

关键调整说明

  • 移除ObjectField上冲突的硬编码MinWidth/MaxWidth配置,改用GUILayout.ExpandWidth(true)让控件自动占满水平布局中Toggle占用后剩余的所有空间,不会撑出横向滚动条
  • 给Toggle设置固定宽度120f,刚好容纳复选框和完整的"Include Children"文本,不会被相邻的ObjectField挤压截断
  • 绘制Toggle前临时调整EditorGUIUtility.labelWidth为95,匹配Toggle的文本长度,避免标签显示不全
  • 新增独立的状态数组存储每一行的勾选值,修复原代码所有行共用一个全局勾选状态的逻辑bug

内容的提问来源于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 16:18:22