using UnityEngine.UIElements;
public class OnAnyValueChangedExample : MonoBehaviour
private VisualElement root;
private VisualElement dialog;
private Label dialogMessage;
private Button confirmButton;
private Button cancelButton;
// Get the root VisualElement from the UI document
var uiDocument = GetComponent<UIDocument>();
root = uiDocument.rootVisualElement;
// Register callbacks for all children recursively
RegisterCallbacksRecursively(root);
// Create the confirmation dialog
CreateConfirmationDialog();
private void RegisterCallbacksRecursively(VisualElement element)
// Register the callback for various change events
element.RegisterCallback<ChangeEvent<bool>>(OnAnyValueChanged);
element.RegisterCallback<ChangeEvent<float>>(OnAnyValueChanged);
element.RegisterCallback<ChangeEvent<int>>(OnAnyValueChanged);
element.RegisterCallback<ChangeEvent<string>>(OnAnyValueChanged);
// Iterate through all children and register the callbacks
foreach (var child in element.Children())
RegisterCallbacksRecursively(child);
private void OnAnyValueChanged(ChangeEvent<bool> evt)
ShowConfirmationDialog($"Boolean value changed in element: {evt.target.name}, new value: {evt.newValue}");
private void OnAnyValueChanged(ChangeEvent<float> evt)
ShowConfirmationDialog($"Float value changed in element: {evt.target.name}, new value: {evt.newValue}");
private void OnAnyValueChanged(ChangeEvent<int> evt)
ShowConfirmationDialog($"Int value changed in element: {evt.target.name}, new value: {evt.newValue}");
private void OnAnyValueChanged(ChangeEvent<string> evt)
ShowConfirmationDialog($"String value changed in element: {evt.target.name}, new value: {evt.newValue}");
private void CreateConfirmationDialog()
dialog = new VisualElement();
dialog.style.position = Position.Absolute;
dialog.style.width = 300;
dialog.style.height = 150;
dialog.style.backgroundColor = new Color(0, 0, 0, 0.8f);
dialog.style.paddingLeft = 10;
dialog.style.paddingRight = 10;
dialog.style.paddingTop = 10;
dialog.style.paddingBottom = 10;
dialog.style.display = DisplayStyle.None;
dialogMessage = new Label();
dialog.Add(dialogMessage);
var buttonContainer = new VisualElement();
buttonContainer.style.flexDirection = FlexDirection.Row;
buttonContainer.style.justifyContent = Justify.SpaceBetween;
confirmButton = new Button() { text = "Confirm" };
confirmButton.clicked += OnConfirmButtonClicked;
buttonContainer.Add(confirmButton);
cancelButton = new Button() { text = "Cancel" };
cancelButton.clicked += OnCancelButtonClicked;
buttonContainer.Add(cancelButton);
dialog.Add(buttonContainer);
private void ShowConfirmationDialog(string message)
dialogMessage.text = message;
dialog.style.display = DisplayStyle.Flex;
private void OnConfirmButtonClicked()
Debug.Log("Changes confirmed.");
dialog.style.display = DisplayStyle.None;
private void OnCancelButtonClicked()
Debug.Log("Changes canceled.");
dialog.style.display = DisplayStyle.None;
// Unregister the callbacks to prevent memory leaks
UnregisterCallbacksRecursively(root);
private void UnregisterCallbacksRecursively(VisualElement element)
// Unregister the callback for various change events
element.UnregisterCallback<ChangeEvent<bool>>(OnAnyValueChanged);
element.UnregisterCallback<ChangeEvent<float>>(OnAnyValueChanged);
element.UnregisterCallback<ChangeEvent<int>>(OnAnyValueChanged);
element.UnregisterCallback<ChangeEvent<string>>(OnAnyValueChanged);
// Iterate through all children and unregister the callbacks
foreach (var child in element.Children())
UnregisterCallbacksRecursively(child);