4.4 KiB
4.4 KiB
UI Toolkit Quick Reference
Common VisualElement Types
Input Controls
TextField- Single/multi-line text inputIntegerField,FloatField,Vector3Field- Numeric inputsToggle- Boolean checkboxButton- Clickable buttonSlider- Value slider with optional input fieldEnumField- Dropdown for enum valuesObjectField- Unity Object reference picker
Layout Containers
VisualElement- Generic container (like<div>)ScrollView- Scrollable areaFoldout- Collapsible sectionTwoPaneSplitView- Resizable split panelListView- Data-driven list with virtualization
Display Elements
Label- Text displayImage- Sprite/Texture displayHelpBox- Info/Warning/Error message boxProgressBar- Progress indicator
USS Flexbox Layout
.container {
flex-direction: row; /* or column */
justify-content: flex-start; /* flex-end, center, space-between */
align-items: stretch; /* flex-start, flex-end, center */
flex-grow: 1;
flex-shrink: 0;
}
USS Common Properties
/* Spacing */
margin: 10px;
padding: 5px 10px;
/* Sizing */
width: 200px;
height: 100px;
min-width: 50px;
max-height: 300px;
/* Background */
background-color: rgb(50, 50, 50);
background-image: url('path/to/image.png');
/* Border */
border-width: 1px;
border-color: rgba(255, 255, 255, 0.2);
border-radius: 4px;
/* Text */
color: rgb(200, 200, 200);
font-size: 14px;
-unity-font-style: bold; /* or italic */
-unity-text-align: middle-center;
Query API Examples
// By name (must set name in UXML)
var button = root.Q<Button>("my-button");
// By class
var items = root.Query<VisualElement>(className: "item").ToList();
// First match
var firstLabel = root.Q<Label>();
// All matches
var allButtons = root.Query<Button>().ToList();
// Complex query
var activeItems = root.Query<VisualElement>()
.Where(e => e.ClassListContains("active"))
.ToList();
Event Handling
// Button click
button.clicked += () => Debug.Log("Clicked!");
// Value change
textField.RegisterValueChangedCallback(evt => {
Debug.Log($"Changed: {evt.previousValue} -> {evt.newValue}");
});
// Mouse events
element.RegisterCallback<MouseDownEvent>(evt => {
Debug.Log($"Mouse down at {evt.localMousePosition}");
});
// Cleanup
void OnDestroy() {
button.clicked -= OnButtonClick;
}
Data Binding
// Bind to SerializedObject
var so = new SerializedObject(targetObject);
rootVisualElement.Bind(so);
// Manual binding
var property = so.FindProperty("fieldName");
var field = new PropertyField(property);
field.BindProperty(property);
Custom VisualElement
public class CustomElement : VisualElement
{
public new class UxmlFactory : UxmlFactory<CustomElement, UxmlTraits> { }
public new class UxmlTraits : VisualElement.UxmlTraits
{
UxmlStringAttribute customAttribute = new UxmlStringAttribute
{ name = "custom-value" };
public override void Init(VisualElement ve, IUxmlAttributes bag,
CreationContext cc)
{
base.Init(ve, bag, cc);
((CustomElement)ve).customValue = customAttribute.GetValueFromBag(bag, cc);
}
}
private string customValue;
public CustomElement()
{
AddToClassList("custom-element");
}
}
Performance Tips
- Use USS classes instead of inline styles
- Cache VisualElement references instead of repeated queries
- Use ListView for large lists (virtualized)
- Avoid excessive rebuilds - update only changed elements
- Use USS variables for maintainable themes
- Minimize UXML nesting for better performance
Common Pitfalls
❌ Querying before CreateGUI finishes
// Wrong
void OnEnable() {
var button = rootVisualElement.Q<Button>(); // null!
}
// Correct
public void CreateGUI() {
visualTree.CloneTree(rootVisualElement);
var button = rootVisualElement.Q<Button>(); // works!
}
❌ Forgetting to name elements
<!-- Wrong: Can't query by name -->
<ui:Button text="Click" />
<!-- Correct -->
<ui:Button name="my-button" text="Click" />
❌ Not cleaning up events
// Memory leak!
button.clicked += OnClick;
// Correct
void OnDestroy() {
button.clicked -= OnClick;
}
Resources
- Unity Manual: UI Toolkit
- Unity Scripting API: UnityEngine.UIElements
- Unity Forum: UI Toolkit section
- Sample Projects: UI Toolkit samples on GitHub