0
\$\begingroup\$

Following up on a previous question about aligning HeaderAttributes, I've been attempting to slightly offset my own custom header attribute so that it's either to the left of center, or to the right of center. The second and fourth headers should be positioned somewhere within the red rectangles, so I'd like to maintain the middle alignment, just with an offset (preferably adjustable), but I'm struggling to figure out how to do that.

an example of how my custom header attribute is currently working, where the second and fourth headers are positioned at anchors middle-left and middle-right, respectively, and should be positioned where the red rectangles are placed instead (one to the left of center, one to the right of center)

I currently have a static class HeaderAlignmentConstants in the same script as my DecoratorDrawer, which looks like this:

public static class HeaderAlignmentConstants
{
    public static GUIStyle LabelLeftAlignStyle { get; } = new GUIStyle(GUI.skin.label)
    {
        fontSize = 12,
        fontStyle = FontStyle.Bold,
        alignment = TextAnchor.MiddleLeft,
    };

    public static GUIStyle LabelLeftCenterStyle { get; } = new GUIStyle(GUI.skin.label)
    {
        fontSize = 12,
        fontStyle = FontStyle.Bold,
        alignment = ???,
    };

    public static GUIStyle LabelCenteredStyle { get; } = new GUIStyle(GUI.skin.label)
    {
        fontSize = 12,
        fontStyle = FontStyle.Bold,
        alignment = TextAnchor.MiddleCenter,
    };

    public static GUIStyle LabelRightCenterStyle { get; } = new GUIStyle(GUI.skin.label)
    {
        fontSize = 12,
        fontStyle = FontStyle.Bold,
        alignment = ???,
    };

    public static GUIStyle LabelRightAlignStyle { get; } = new GUIStyle(GUI.skin.label)
    {
        fontSize = 12,
        fontStyle = FontStyle.Bold,
        alignment = TextAnchor.MiddleRight,
    };
}

And in that drawer, I'm basically doing the following for each case:

if (myHeader != null && myHeader.alignment == HeaderAlignment.SomeAlignment)
{
    EditorGUI.LabelField(headerRect, new GUIContent(myHeader.headerTitle),
                         HeaderAlignmentConstants.SomeAlignmentStyle);

}

Because TextAnchor is an enumeration,

  1. I'm uncertain as to how it is working, because simply creating and populating a new enumeration called "MyTextAnchor" or something would not magically align the attribute (ctrl + click on TextAnchor only redirects to the definition of the enum, not wherever the place is that the enum is utilized), and attempting to add a value to, say, TextAnchor.MiddleLeft doesn't seem to do anything.

  2. I don't think that something like casting TextAnchor to another field type would work (for instance, I considered (int)TextAnchor, but I think that this would only return an int that would not be useful for much of anything).

With all of that, how can I adjust my text anchoring for the desired implementation?

EDIT: I found this post on the Unity forum that suggested using GUILayout.HorizontalScope() and GUILayout.VerticalScope() to achieve the effect of what is essentially indenting the label field, but I'm not finding success with it (granted, I'm using EditorGUILayout versions instead, but I don't see where that would affect much). I tried modifying the code as follows:

using (new EditorGUILayout.HorizontalScope())
{
    EditorGUILayout.Space(100f);

    using (new EditorGUILayout.VerticalScope())
    {
        if (myHeader != null && myHeader.alignment == HeaderAlignment.LeftOfCenter)
        {
            EditorGUI.LabelField(headerRect, new GUIContent(myHeader.headerTitle),
                                 HeaderAlignmentConstants.LabelLeftCenterStyle);
        }
    }   
}

EDIT 2: The more that I dig into IMGUI, the more I'm finding that the suggestion is to just use the UI Toolkit (for which the documentation seems to be sparse or confusing at best), so for now, I've put together something a bit hackish that kind of achieves what I'm looking for by just...drawing separate Rect objects where necessary (not optimal, probably):

MyHeaderAttribute myHeader = (MyHeaderAttribute)attribute;
Rect headerRect = new Rect(position.x - 20, position.y, position.width + 25, position.height);
Rect headerLOCRect = new Rect(position.min.x + (position.width / 5f), position.y, position.width, position.height);
Rect headerROCRect = new Rect(position.min.x - (position.width / 5f), position.y, position.width, position.height);
Rect headerBGColorRect = new Rect(position.x - 20, position.y, position.width + 25, position.height);
Color headerBGColor = new Color(0.125f, 0.125f, 0.125f, 1);


EditorGUI.DrawRect(headerBGColorRect, headerBGColor);

// see above for `LabelField` implementation

the label fields kind of adjust to where they should, but not quite

\$\endgroup\$
4
  • \$\begingroup\$ What you want is best achieved by adjusting the Rect, not by changing the GUIStyle. You should spend some time learning how to use the IMGUI functions in the EditorGUI class. \$\endgroup\$
    – Kevin
    Commented May 2 at 22:29
  • \$\begingroup\$ Looking at the documentation, and having done a search, it seems like IMGUI maybe would use more resources since it occurs every frame, and might only be for in-game GUI applications--is that not the case? Also, what do you mean by "adjusting the Rect"--in what way? I discovered EditorGUI.indentLevel and played around with incrementing that, but it seemed to be adjusting the indent for everything below wherever it was incremented. \$\endgroup\$
    – NJJ_002
    Commented May 3 at 22:57
  • 1
    \$\begingroup\$ EditorGUI gives you access to IMGUI functions that work in the Editor. You generally shouldn't worry about resources used by Editor-only features like PropertyDrawers. Performance in the Editor is less critical, and the performance impact of IMGUI is generally going to be negligible compared to the rest of the Editor's overhead. \$\endgroup\$
    – Kevin
    Commented May 3 at 23:14
  • \$\begingroup\$ I don't have time at the moment to write an answer that uses the Rect to adjust the position of the header. However, you should be able to learn how it works for yourself by searching for tutorials on Unity's IMGUI or EditorGUI functions (make sure not to confuse EditorGUI with EditorGUILayout - the latter manages the Rect for you but isn't usable in Property Drawers). For general questions, you will get answers much faster by learning how to find web resources rather than posting a question here and waiting for an answer. \$\endgroup\$
    – Kevin
    Commented May 3 at 23:17

0

You must log in to answer this question.

Browse other questions tagged .