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
相关产品推荐
相关产品推荐

