Tips, Tricks and Best Practices

Avoid auto-magic

It is often tempting to make something that will automatically change or fix a value in a drawer. It needs to be done anyway, so why bother the user with it?

The problem with this is that you end up hiding a potential issue. And this is especially the case with drawers, where the auto-magic will only run when the object is actually being inspected. This could potentially lead to weird and confusing situations where a piece of code behaves in two different ways depending upon whether or not the object is currently being inspected.

On the other side, if you warn or show the user that there is an issue, then they become aware of it, can fix it, and now that the issue may also be present elsewhere, and needs to be fixed there as well.

Be careful with conversions

Converting from a long to an int and back to a long again can cause a loss of data. So if you find yourself needing to make such a conversion in order to use a method, then it is a good idea to only assign a change in value, when the user has actually changed the value in the inspector themselves.

You can use the EditorGUI.BeginChangeCheck and EndChangeCheck methods for this effect:

long newValue = SirenixEditorFields.IntField((int)this.longValue));

if (EditorGUI.EndChangeCheck())
	this.longValue = newValue;

Use rects instead of layout

Usings IMGUI's layout system is great for many usecases, but often it is simpler to just get a single Rect and use math to manipulate and place elements manually with the Rect. As a bonus this will also result in much faster drawing code as opposed to using layout groups.

Odin defines a lot of helpful extension methods for the Rect struct that are useful for this kind of manipulation and positioning.

Rect rect = EditorGUILayout.GetControlRect();

if (label != null)
	// The PrefixLabel method eats the first part of rect that is used by the label.
	rect = EditorGUI.PrefixLabel(rect, label); 

// Take 80 pixels from the right side of the int field...
value = SirenixEditorFields.IntField(rect.SubXMax(80), value);

// ... and use them to make a button.
if (GUI.Button(rect.AlignRight(80), "Set Zero"))
	value = 0;