Added spacing on fields when using BeginBox() and EndBox() in custom drawer

Issue #910 new
Danae Dekker created an issue

When using a OdingValueDrawer for a custom asset, the spacing of property fields changes depending on whether or not SirenixEditorGUI.BeginBox() and SirenixEditorGUI.EndBox() are used. It seems that the fields being drawn outside of the box adjust their spacing to the fields inside of the box, effectively making the fields a few pixels smaller on both sides. I’ve only tested this in custom drawer code, so I’m not sure if this issue will persist in other code that uses boxes.

The code I’m using to draw the fields is thefollowing:

namespace [...]
{
    [CustomPropertyDrawer(typeof(SceneReference))]
    [CanEditMultipleObjects]
    public class SceneReferenceDrawer : OdinValueDrawer<SceneReference>
    {
        // Properties of the scene reference
        private InspectorProperty _scenePath;
        private InspectorProperty _sceneAsset;
        private InspectorProperty _isDirty;

        private bool _expanded = false;


        // Initialize the drawer
        protected override void Initialize()
        {
            _scenePath = Property.Children["_scenePath"];
            _sceneAsset = Property.Children["_sceneAsset"];
            _isDirty = Property.Children["_isDirty"];
        }

        // Draw the property layout
        protected override void DrawPropertyLayout(GUIContent label)
        {
            // Mark the proerty as not dirty
            if ((bool)_isDirty.ValueEntry.WeakSmartValue)
                _isDirty.ValueEntry.WeakSmartValue = false;

            // Draw the scene asset
            if ((SceneAsset)_sceneAsset.ValueEntry.WeakSmartValue != null)
            {
                // Draw a foldout if an asset is selected
                _expanded = SirenixEditorGUI.Foldout(_expanded, label, out var fieldPosition);
                _sceneAsset.ValueEntry.WeakSmartValue = SirenixEditorFields.UnityObjectField(fieldPosition, (SceneAsset)_sceneAsset.ValueEntry.WeakSmartValue, typeof(SceneAsset), false);
            }
            else
            {
                // Draw a plain labelif no asset is selected
                _sceneAsset.Draw(label);
            }

            // Get the build scene
            var buildScene = SceneBuildUtils.GetBuildScene((SceneAsset)_sceneAsset.ValueEntry.WeakSmartValue);
            if (buildScene.scene == null)
                _scenePath.ValueEntry.WeakSmartValue = "";

            // Deaw the asset info
            if ((SceneAsset)_sceneAsset.ValueEntry.WeakSmartValue != null && _expanded)
            {
                SirenixEditorGUI.BeginBox();

                // Draw the build settings fields
                GUI.enabled = false;

                var buildIndexLabel = new GUIContent("Build Index");
                if (buildScene.buildIndex > -1)
                    SirenixEditorFields.IntField(buildIndexLabel, buildScene.buildIndex);
                else
                    SirenixEditorFields.TextField(buildIndexLabel, "Not in build");

                var assetGuidLabel = new GUIContent("Asset GUID");
                SirenixEditorFields.TextField(assetGuidLabel, buildScene.assetGuid.ToString());

                var assetPathLabel = new GUIContent("Asset Path");
                SirenixEditorFields.TextField(assetPathLabel, buildScene.assetPath);

                GUI.enabled = true;

                // Draw the build settings buttons
                GUILayout.Space(4.0f);

                var buttonsPosition = EditorGUILayout.GetControlRect(false);

                var buildOpenScenePosition = buttonsPosition.Split(0, 3);
                if (GUI.Button(buildOpenScenePosition, new GUIContent("Open scene", EditorIcons.Folder.Highlighted), EditorStyles.miniButtonLeft))
                    EditorSceneManager.OpenScene((string)_scenePath.ValueEntry.WeakSmartValue, OpenSceneMode.Additive);

                var buildAddRemovePosition = buttonsPosition.Split(1, 3);
                using (new EditorGUI.DisabledScope(SceneBuildUtils.IsReadOnly()))
                {
                    if (buildScene.buildIndex > -1)
                    {
                        if (GUI.Button(buildAddRemovePosition, new GUIContent("Remove from build", EditorIcons.Minus.Highlighted), EditorStyles.miniButtonMid))
                            SceneBuildUtils.RemoveBuildScene(buildScene);
                    }
                    else
                    {
                        if (GUI.Button(buildAddRemovePosition, new GUIContent("Add to build", EditorIcons.Plus.Highlighted), EditorStyles.miniButtonMid))
                            SceneBuildUtils.AddBuildScene(buildScene);
                    }
                }

                var buildSettingsPosition = buttonsPosition.Split(2, 3);
                if (GUI.Button(buildSettingsPosition, new GUIContent("Build settings", EditorIcons.SettingsCog.Highlighted), EditorStyles.miniButtonRight))
                    SceneBuildUtils.OpenBuildSettings();

                SirenixEditorGUI.EndBox();
            }
        }
    }
}

When the fields inside of the box aren’t drawn because the foldout isn’t expanded, the spacing of the _sceneAsset field appears as normal, but when the box is drawn, the extra spacing is applied.

The same added spacing appears when I use Unity’s own EditorGUILayout.Space(), but it doesn’t appear when using GUILayout.Space() in line 71.

If this behaviour is intended is there a way to disable it in custom drawers? I’m using Unity 2021.3.16f1 with Odin Inspector 3.1.10.0 (editor only mode) on Windows 11.

Comments (0)

  1. Log in to comment