EditorGUIUtility is a foundational utility class in Unity’s editor scripting API, desinged to augment and streamline common editor UI tasks. Unlike EditorGUI, which handles immediate-mode control rendering, EditorGUIUtility provides stateless helper functions—ranging from asset loading and coordinate trensformations to object selection workflows and visual feedback mechanisms.
Loading Editor Assets Safely
To load editor-specific assets (e.g., icons, textures, or fonts) at runtime, Unity requires them to reside in the Assets/Editor Default Resources/ folder—a reserved directory that must be named exactly with a space (not EditorDefaultResources). Two primary loading methods exist:
EditorGUIUtility.Load<T>(string path): Returnsnullif the asset is missing or invalid. Safe for optional resources.EditorGUIUtility.LoadRequired<T>(string path): Throws an exception on failure—ideal for critical UI assets where absence indicates misconfiguration.
Both require the full relative path *including file extension*, e.g., "Icons/SettingsIcon.png".
Example: Asset Loading Panel
public class AssetLoaderWindow : EditorWindow
{
[MenuItem("Tools/Asset Loader")]
public static void ShowWindow() => GetWindow<AssetLoaderWindow>("Asset Loader").Show();
private Texture2D _icon;
private Texture2D _fallback;
void OnGUI()
{
if (GUILayout.Button("Load Icon (Safe)"))
_icon = EditorGUIUtility.Load<Texture2D>("Icons/ToolIcon.png");
if (GUILayout.Button("Load Icon (Required)"))
_fallback = EditorGUIUtility.LoadRequired<Texture2D>("Icons/Fallback.png");
if (_icon != null)
GUI.DrawTexture(new Rect(10, 50, 64, 64), _icon);
if (_fallback != null)
GUI.DrawTexture(new Rect(90, 50, 64, 64), _fallback);
}
}
Object Selection and Visual Feedback
For interactive resource discovery, EditorGUIUtility.ShowObjectPicker<T> launches Unity’s built-in object browser with filtering support:
defaultObject: Pre-selects an asset in the picker.allowSceneObjects: Enables searching scene hierarchy (e.g., forGameObject).filter: Text-based name filter (e.g.,"normal"matchesrock_normal.png).controlID: Legacy parameter—always pass0.
Selection results are retrieved via EditorGUIUtility.GetObjectPickerObject(). Because the picker operates asynchronously, your window must listen for two command events:
"ObjectSelectorUpdated": Fired when user selects a new item."ObjectSelectorClosed": Fired when the picker closes (regardless of selection).
Additionally, EditorGUIUtility.PingObject() highlights the selected asset in the Project or Hierarchy view—providing instant visual context.
Example: Picker Integration
public class PickerDemoWindow : EditorWindow
{
[MenuItem("Tools/Picker Demo")]
public static void ShowWindow() => GetWindow<PickerDemoWindow>("Picker Demo").Show();
private Texture2D _selectedTexture;
void OnGUI()
{
if (GUILayout.Button("Open Texture Picker"))
EditorGUIUtility.ShowObjectPicker<Texture2D>(null, false, "ui", 0);
// Handle picker events
if (Event.current.commandName == "ObjectSelectorUpdated" ||
Event.current.commandName == "ObjectSelectorClosed")
{
var picked = EditorGUIUtility.GetObjectPickerObject();
if (picked is Texture2D tex)
_selectedTexture = tex;
}
if (GUILayout.Button("Ping Selected Texture") && _selectedTexture != null)
EditorGUIUtility.PingObject(_selectedTexture);
}
}
Inter-Window Communication and Coordinate Conversion
Unity supports lightweight event-driven communication between editor windows using command events:
- Create an event with
EditorGUIUtility.CommandEvent("MyCommand"). - Send it via
window.SendEvent(event)—the target window will auto-focus if minimized. - Recieve it by checking
Event.current.type == EventType.ExecuteCommandand matchingcommandName.
For precise UI positioning, convert between coordinate spaces:
EditorGUIUtility.GUIToScreenPoint(Vector2): Transforms from local window space to screen pixels.EditorGUIUtility.ScreenToGUIPoint(Vector2): Converts screen coordinates back to local GUI space (useful for overlays or tooltips).
Note: These conversions respect GUI.BeginGroup() offsets and layout scaling.
Custom Cursor Behavior
Enhance UX by changing the cursor over interactive regions using EditorGUIUtility.AddCursorRect():
if (GUILayout.Button("Hover Me"))
{
// Apply custom cursor only while mouse is over this button
EditorGUIUtility.AddCursorRect(GUILayoutUtility.GetLastRect(), MouseCursor.Link);
}
Supported cursors include MouseCursor.ResizeVertical, MouseCursor.Pan, MouseCursor.Zoom, and MouseCursor.CustomCursor for user-defined textures.
Visual Swatches for Editors
Render compact previews alongside property fields:
EditorGUIUtility.DrawColorSwatch(Rect, Color): Draws a filled rectangle with border highlighting for color fields.EditorGUIUtility.DrawCurveSwatch(Rect, AnimationCurve, SerializedProperty, Color, Color): Renders a miniature curve preview with optional background and stroke colors—commonly used withEditorGUILayout.CurveField.
Example: Swatch Rendering
public class SwatchDemoWindow : EditorWindow
{
[MenuItem("Tools/Swatch Demo")]
public static void ShowWindow() => GetWindow<SwatchDemoWindow>("Swatch Demo").Show();
private Color _swatchColor = Color.cyan;
private AnimationCurve _swatchCurve = AnimationCurve.Linear(0, 0, 1, 1);
void OnGUI()
{
_swatchColor = EditorGUILayout.ColorField("Swatch Color", _swatchColor);
EditorGUIUtility.DrawColorSwatch(new Rect(120, 30, 24, 24), _swatchColor);
_swatchCurve = EditorGUILayout.CurveField("Swatch Curve", _swatchCurve);
EditorGUIUtility.DrawCurveSwatch(
new Rect(10, 70, 100, 60),
_swatchCurve,
null,
Color.green,
new Color(0.2f, 0.2f, 0.2f)
);
}
}