[Help] Horizontally cut off visuals in custom editor window

I’m working on a custom editor window that interfaces with a modular state machine system I’m building. Under the hood, this window is editing the values that are saved in a list of a data structure I made. The left column is for selecting which element of the list you would like to edit, and then the state of that element appears on the right side.

Here is a screenshot of how it’s supposed to look:

I then attempted to put both the left selection column and the right data view section into scroll views, because it’s possible for them to grow enough that they would need to be able to scroll to show everything. The selection column worked with no issue, but the data view section got cut off horizontally, as if there’s a grey box just on top of it obscuring the left side.

I thought maybe it was an issue with the property drawer for the data structure, but I tried replacing it with just a regular label field to see and got the same result. I have searched online and have not been able to find anybody else having the same issue, though it’s possible I just don’t know the right words to search. Any help would be appreciated.

I am currently working in Unity version 2022.3.17f1, and the only files in this project are the ones related to this data structure and display system, because it’s a system I originally built for a different project and am now working on making into a generally applicable tool, to hopefully be made into a publicly available package.

It’s worth noting this is by far the deepest I’ve gotten into custom editor functionality, so I’m not exactly an expert on the field, I’ve been learning as I go

This looks like as if you had three elements in a column layout. You probably only have to move the right-side elements onto the scroll view so they become children of it.

Without seeing your UI Builder layout and element styles it’s hard to tell more though.

I’m not actually using UI builder, this is being done in code by making a class that inherits UnityEditor.EditorWindow and implementing a custom OnGUI()

Pasting the entire class here seems excessive but here’s the most relevant pieces:

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

public class StateTransitionsWindow : EditorWindow
{
    ...    
    public static void ShowWindow(ATStateMachine machine)
    {
        if (listStyle == null || selectedStyle == null)
        {
            InitTextures();
            InitStyles();
        }
        window = GetWindow<StateTransitionsWindow>("Transition Editor");
        window.minSize = new Vector2(600, 300);
        serializedObject = new SerializedObject(machine as Object);
    }
    ...
    private void OnGUI()
    {
        DrawLayouts();    // define rects for window layout
        try
        {
            DrawList();         // buttons to select which element of the list is being edited
            DrawListButtons();  // add/remove, move up/down buttons
            DrawData();         // display currently selected transition
            DrawButtons();      // save/exit buttons
        }
        catch { Close(); }
    }
    ...
    void DrawData()
    {
        GUILayout.BeginArea(datascrollrect);
        dataScrollPos = GUI.BeginScrollView(datascrollrect, dataScrollPos, datascrollview, false, false, GUIStyle.none, GUI.skin.GetStyle("verticalScrollbar")); // THE PROBLEM

        if (selected >= 0)
            EditorGUILayout.PropertyField(transitionsProperty.GetArrayElementAtIndex(selected));

        GUI.EndScrollView(); // THE PROBLEM
        GUILayout.EndArea();
    }
}

The lines I marked as “the problem” are the scroll view I’m talking about. Commenting out those two lines causes the window to look like screenshot #1 in my original post

This is IMGUI code, not UITK. :wink:

Of all things you shouldn’t be using IMGUI for editor tooling.

Like I said, I’m relatively new to this. I started this process by basically google searching “unity custom editor” and watching some youtube videos and reading documentation. Sorry haha

Out of curiosity, why do you say you shouldn’t use IMGUI for editor tooling?

IMGUI’s pretty old and doing certain things in it is substantially harder than doing the same in UI Toolkit (though the reverse is true in some cases, too). Though that assumes one is over the initial skill hurdle for both systems.

I’d be curious to see your DrawLayouts method. It looks like to me that some of your rects are probably wrong? You can probably just use GUILayout methods like Begin/EndHorizontal to organise everything, rather than prep a bunch of rects.

IMGUI requires you to draw the entire GUI in code every time it updates since IMGUI is stateless.
You end up with a gigantic method of GUI calls with conditional blocks that may or may not run for every iteration and eventually, given even basic complexity, you run into all sorts of logic and layout issues that you can only debug with logs and the debugger.

Whereas if you use UI Toolkit you get to design your GUI interactively with UI Builder, you can test the GUI (without logic) right within the UI Builder and then hook it up with only the code that you need to perform when something is done with the GUI.

Of course you can still program the entire GUI with UI Elements but even that is far easier and more closely resembles the way you work with GameObjects (instantiate and it’ll be there until you destroy it) or any other stateful API.

1 Like

I find that using the GUILayout methods is great for things like grouping up multiple related fields, but it starts to get really complex and can easily cause issues that are hard to debug if they end up nested too many times, but that’s my personal opinion. Using rects lets me think about the overall layout and then once that’s set up I can just worry about each piece individually

Here’s that method (all the variables that are used in here exist as private fields in the overall class):

void DrawLayouts()
{
    if(window == null) { Close(); return; }
    windowpos = window.position;

    // overall box for left side column
    listview.width = EditorGUIUtility.currentViewWidth * 0.35f;
    listview.height = windowpos.height - 90;
    listview.x = 0;
    listview.y = 0;

    // available scrollview rect for list column
    float singleLine = EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing;
    listscrollrect.width = listview.width;
    listscrollrect.height = listview.height - singleLine;
    listscrollrect.x = listview.x;
    listscrollrect.y = singleLine;

    // actual needed area for list column
    listscrollview.width = listview.width;
    listscrollview.height = transitionNames.Count * singleLine;
    listscrollview.x = 0;
    listscrollview.y = singleLine;

    // box for Add/Delete/Move up/down buttons
    listbuttonsview.width = listview.width;
    listbuttonsview.height = 40;
    listbuttonsview.x = 0;
    listbuttonsview.y = windowpos.height - 90;

    // available scrollview rect for data column
    datascrollrect.width = EditorGUIUtility.currentViewWidth * 0.6f;
    datascrollrect.height = windowpos.height - 50;
    datascrollrect.x = EditorGUIUtility.currentViewWidth * 0.375f;
    datascrollrect.y = 0;

    // needed area for data column
    datascrollview.width = datascrollrect.width;
    datascrollview.height = selected >= 0 ? EditorGUI.GetPropertyHeight(transitionsProperty.GetArrayElementAtIndex(selected)) : 0;
    datascrollview.x = datascrollrect.x;
    datascrollview.y = 0;

    // bottom bar for Save/Exit buttons
    buttonsview.width = EditorGUIUtility.currentViewWidth;
    buttonsview.height = 50 - EditorGUIUtility.standardVerticalSpacing;
    buttonsview.x = 0;
    buttonsview.y = windowpos.height - 50;
}

Thanks for the info! Interesting that I didn’t come across this in my initial searches while trying to teach myself how to do this. Maybe I should look into that after all. I have actually wondered why the system didn’t seem to have any state functionality, since redoing every check every frame update seems like a waste of resources. I guess that answers that question. Will that UI toolkit setup be saved in a way that will come with the system if/when I export it out as a package?