How do I implement Draggable Properties with custom Labels in Editor or PropertyDrawer?

For the sake of simplicity I will explain this on a simple example.
I’m having a Monobehaviour or a custom [Serializable] class that holds multiple ints:

class HoldingInts : MonoBehaviour {
	public int A;
	public int B;
	public int C;
}

The default Inspector puts a label in front of those three properties that I can click and drag to change the number without having to type.

Now, these take a lot of space, so I want to have an Editor or PropertyDrawer that put them side by side, like the X,Y,Z components of a Vector3 for example, so I do this:

GUIStyle overflowStyle = new GUIStyle();
overflowStyle.clipping = TextClipping.Overflow;
GUILayoutOption w8 = GUILayout.Width(8);
GUILayoutOption w25 = GUILayout.Width(25);
GUILayoutOption xw = GUILayout.ExpandWidth(true);

EditorGUILayout.BeginHorizontal();
EditorGUILayout.PrefixLabel("My Ints");
EditorGUILayout.LabelField("A", overflowStyle, w8);
EditorGUILayout.PropertyField(prop.FindPropertyRelative("A"), GUIContent.none, w25, xw);
EditorGUILayout.LabelField("B", overflowStyle, w8);
EditorGUILayout.PropertyField(prop.FindPropertyRelative("B"), GUIContent.none, w25, xw);
EditorGUILayout.LabelField("C", overflowStyle, w8);
EditorGUILayout.PropertyField(prop.FindPropertyRelative("C"), GUIContent.none, w25, xw);
EditorGUILayout.EndHorizontal();

Which gives me what I want visually, but my custom labels are not connected to the properties, so I can’t click and drag them to change the numbers.

Is it possible to connect those custom labels to the properties?

After some tinkering, I came to the following solution:

[CustomPropertyDrawer(typeof(HoldingInts))]
public class HoldingIntsInspector : PropertyDrawer
{
    private float a = 17;
    public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label)
    {
        float width = position.width * 0.25f;

        Rect rect = new Rect(position);
        rect.width = width;

        EditorGUI.LabelField(rect, label);
        rect.x += width;

        float labelWidthTmp = EditorGUIUtility.labelWidth;
        EditorGUIUtility.labelWidth = 24f; // your label width (8) x3
        EditorGUI.PropertyField(rect, prop.FindPropertyRelative("A"), new GUIContent("A"));
        rect.x += width;
        EditorGUI.PropertyField(rect, prop.FindPropertyRelative("B"), new GUIContent("B"));
        rect.x += width;
        EditorGUI.PropertyField(rect, prop.FindPropertyRelative("C"), new GUIContent("C"));

        EditorGUIUtility.labelWidth = labelWidthTmp;
    }
}

You will probably need to tune this a bit to get perfect effect, but this should be a decent starting point. I went PropertyDrawer way, as I never used it before, so I was able to learn something new as well :wink: