For my game(an endless runner) I want to accelerate the work flow of creating obstacle patterns for sections of the game and want to create a custom editor window. I followed the “UIElements: First Steps” tutorial in the Learn site and my vision for the custom editor window is similar to the results of the tutorial(with more features of course) except that I’d like the editor to be context sensitive, as in I’d like for the editor window to show a label saying something like “Select a Section” and once the section is selected, the rest of the editor is drawn based on information of the section(ie list of obstacle patterns it may already have, load obstacle pattern button, create obstacle pattern button). I edited the tutorial editor window and this is what I came up with
using System;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
public class QuickTool : EditorWindow
{
private VisualElement root;
private Label selectTargetLabel;
private TemplateContainer templateContainer;
private TargetToSelect target;
[MenuItem("QuickTool/Open _%#T")]
public static void ShowWindow()
{
EditorWindow window = GetWindow<QuickTool>();
window.titleContent = new GUIContent("QuickTool");
window.minSize = new Vector2(250, 50);
}
private void OnEnable()
{
root = rootVisualElement;
root.styleSheets.Add(Resources.Load<StyleSheet>("QuickTool_Style"));
OnSelectionChange();
}
private void OnSelectionChange()
{
if (Selection.activeGameObject)
{
TargetToSelect targetToSelect = Selection.activeGameObject.GetComponent<TargetToSelect>();
target = targetToSelect;
}
else
target = null;
if (target == null)
{
if (!root.Contains(selectTargetLabel))
{
selectTargetLabel = new Label("Select a Target");
root.Add(selectTargetLabel);
}
if (templateContainer != null)
templateContainer.RemoveFromHierarchy();
}
else
{
if (selectTargetLabel != null)
selectTargetLabel.RemoveFromHierarchy();
DrawWindow();
}
}
private void DrawWindow()
{
if (!root.Contains(templateContainer))
{
VisualTreeAsset quickToolVisualTree = Resources.Load<VisualTreeAsset>("QuickTool_Main");
templateContainer = quickToolVisualTree.CloneTree();
UQueryBuilder<Button> toolButtons = templateContainer.Query<Button>();
toolButtons.ForEach(SetupButton);
root.Add(templateContainer);
}
}
private void SetupButton(Button button)
{
VisualElement buttonIcon = button.Q(className: "quicktool-button-icon");
string iconPath = "Icons/" + button.parent.name + "_icon";
Texture2D iconAsset = Resources.Load<Texture2D>(iconPath);
buttonIcon.style.backgroundImage = iconAsset;
button.clickable.clicked += () => CreateObject(button.parent.name);
button.tooltip = button.parent.name;
}
private void CreateObject(string primitiveTypeName)
{
PrimitiveType pt = (PrimitiveType)Enum.Parse(typeof(PrimitiveType), primitiveTypeName, true);
GameObject go = ObjectFactory.CreatePrimitive(pt);
go.transform.position = Vector3.zero;
}
}
Now what I’d like to know is, if this is the best approach for hiding the rest of the window (while targetToSelect is not the active game object)? It’s working for me but I’m wondering if there is a more efficient way than checking if visual elements are not null to remove them from the root visual element. By the way this is just code for me figuring out how to do it right, it’s not in with my game project hence not referring to any obstacle patterns and stuff. I’m definitely new to extending the editor with UIElements so any help is greatly appreciated.