CreateChildPropertyGUI(VisualElement, SerializedProperty, SerializedProperty)
Creates the GUI for a single attribute of the UXML serialized data.
Read time 2 minutesLast updated 12 days ago
Definition
- Type: Method
- Namespace: Unity.UIToolkit.Editor
- Assembly: UnityEditor
protected virtual void CreateChildPropertyGUI(VisualElement container, SerializedProperty property, SerializedProperty childProperty)
Parameters
The parent element to add the content to.
The serialized property that represents the UXML serialized data instance.
The serialized property for the attribute to draw.
Remarks
The default implementation adds a UxmlAttributeField bound to . Override this method to draw specific attributes with a custom layout, and call the base method for the rest.
childPropertyThe following example draws specific attributes with custom layouts and action buttons.
Examples
// Override CreateChildPropertyGUI to render specific properties with custom layouts.//// This example targets an InfoPanel element with two string [UxmlAttribute] properties:// - "text": a freeform description rendered as a multiline TextField with a Clear button.// - "documentationUrl": a URL rendered as a single-line TextField with an Open button.//// Both fields use a UxmlAttributeFieldDecorator so they retain override and binding affordances.// All other properties fall back to the default UxmlAttributeField rendering via the base class.[CustomPropertyDrawer(typeof(InfoPanel.UxmlSerializedData))]public class InfoPanelDrawer : UxmlSerializedDataPropertyDrawer{ protected override void CreateChildPropertyGUI(VisualElement container, SerializedProperty property, SerializedProperty childProperty) { switch (childProperty.name) { case "text": container.Add(BuildMultilineFieldWithClear(property, childProperty)); break; case "documentationUrl": container.Add(BuildUrlFieldWithOpen(property, childProperty)); break; default: base.CreateChildPropertyGUI(container, property, childProperty); break; } } // Builds a row with a multiline TextField inside a UxmlAttributeFieldDecorator and a Clear button. static VisualElement BuildMultilineFieldWithClear(SerializedProperty property, SerializedProperty childProperty) { // Cache the path and the object — both properties are references that may be recycled after // this method returns, so the button callback must not touch either one. string propertyPath = childProperty.propertyPath; SerializedObject serializedObject = property.serializedObject; VisualElement row = new VisualElement(); row.style.flexDirection = FlexDirection.Row; UxmlAttributeFieldDecorator decorator = new UxmlAttributeFieldDecorator(); TextField textField = new TextField(childProperty.displayName); textField.bindingPath = propertyPath; textField.multiline = true; textField.style.flexGrow = 1; decorator.Add(textField); row.Add(decorator); row.Add(new Button(() => { SerializedProperty serializedProperty = serializedObject.FindProperty(propertyPath); if (serializedProperty != null) { serializedProperty.stringValue = string.Empty; serializedObject.ApplyModifiedProperties(); } }) { text = "Clear" }); return row; } // Builds a row with a single-line TextField inside a UxmlAttributeFieldDecorator and an Open button. static VisualElement BuildUrlFieldWithOpen(SerializedProperty property, SerializedProperty childProperty) { string propertyPath = childProperty.propertyPath; SerializedObject serializedObject = property.serializedObject; VisualElement row = new VisualElement(); row.style.flexDirection = FlexDirection.Row; UxmlAttributeFieldDecorator decorator = new UxmlAttributeFieldDecorator(); TextField textField = new TextField(childProperty.displayName); textField.bindingPath = propertyPath; textField.style.flexGrow = 1; decorator.Add(textField); row.Add(decorator); row.Add(new Button(() => { SerializedProperty serializedProperty = serializedObject.FindProperty(propertyPath); if (serializedProperty != null && !string.IsNullOrEmpty(serializedProperty.stringValue)) Application.OpenURL(serializedProperty.stringValue); }) { text = "Open" }); return row; }}