Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Extensions for UIElements
using System;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using JetBrains.Annotations;
using UnityEngine.UIElements;
// ReSharper disable once CheckNamespace
namespace UnityEditor
[SuppressMessage("ReSharper", "InconsistentNaming")]
[SuppressMessage("ReSharper", "StringLiteralTypo")]
[SuppressMessage("ReSharper", "CommentTypo")]
public static class EditorWindowExtensions
/// <summary>
/// Loads the visual tree.
/// <para>
/// This method loads the visual tree and associated style sheet using default Unity conventions,
/// that is, UXML and USS files are expected to be located next to this instance script asset.
/// </para>
/// <para>
/// Declared instance fields that derive from <see cref="VisualElement" /> will be assigned
/// the matching element instance found when searching the visual tree.
/// </para>
/// </summary>
/// <param name="window">
/// Source window.
/// </param>
/// <exception cref="ArgumentNullException">
/// <paramref name="window" /> is <c>null</c>.
/// </exception>
/// <exception cref="FileNotFoundException">
/// Associated UMXL or USS file could not be found.
/// </exception>
/// <exception cref="InvalidOperationException">
/// A declared instance field deriving from <see cref="VisualElement" /> could not be found in the visual tree.
/// </exception>
public static void LoadVisualTree([NotNull] this EditorWindow window)
if (window == null)
throw new ArgumentNullException(nameof(window));
var script = MonoScript.FromScriptableObject(window);
var path = AssetDatabase.GetAssetPath(script);
var xml = Path.ChangeExtension(path, "uxml");
var css = Path.ChangeExtension(path, "uss");
var asset = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(xml);
if (asset == null)
throw new FileNotFoundException("Associated UXML file could not be found.");
var sheet = AssetDatabase.LoadAssetAtPath<StyleSheet>(css);
if (sheet == null)
throw new FileNotFoundException("Associated USS file could not be found.");
var tree = asset.CloneTree();
var fields = window
.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.DeclaredOnly)
.Where(s => typeof(VisualElement).IsAssignableFrom(s.FieldType))
foreach (var field in fields)
var name = field.Name;
var type = field.FieldType;
var element = tree.Q(name);
if (element == null)
throw new InvalidOperationException($"Element '{name}' of type '{type}' could not be found in visual tree.");
field.SetValue(window, element);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.