Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Check for changed fields in a visual tree.

Discussion in 'UI Toolkit' started by tmhbrts, May 12, 2020.

  1. tmhbrts

    tmhbrts

    Joined:
    Dec 24, 2013
    Posts:
    13
    Hi,

    I am trying to find a way to perform this IMGUI-based code using UIElements:

    Code (CSharp):
    1. void OnInspectorGUI()
    2. {
    3.     if (GUI.changed)
    4.     {
    5.         //Do something
    6.     }
    7. }
    I am trying to achieve to 'do something' whenever any of the fields in a visual tree are altered.
     
  2. uMathieu

    uMathieu

    Unity Technologies

    Joined:
    Jun 6, 2017
    Posts:
    386
    UI Toolkit uses events to react to changes in field values. On a field, you can use myField.RegisterValueChangeCallback(...)
     
  3. tmhbrts

    tmhbrts

    Joined:
    Dec 24, 2013
    Posts:
    13
    I get that. But now how do I check for all the fields in a visual tree without repetition? For example, if I want to mark the scene dirty for any field having its value changed in a custom editor.
     
  4. uMathieu

    uMathieu

    Unity Technologies

    Joined:
    Jun 6, 2017
    Posts:
    386
    If you're using DataBinding with SerializedObjects, the scene dirtying should be done automatically.

    If you don`t use bindings, a workaround you can use now is to register to ChangeEvents at the root of your visual tree as the change events will bubble up the hierarchy after being handled at the target. While you unfortunately need to register to all known types of ChangeEvents, you only need to do it on one element.

    Code (CSharp):
    1.  
    2. // This will come in in the next 20.2 release, sent from PropertyFields
    3. // evt.target refers to the original field that triggered the change.
    4. rootElement.RegisterCallback<SerializedPropertyChangeEvent>((changeEvent) => DirtyStuff());
    5.  
    6. rootElement.RegisterCallback<ChangeEvent<int>>((evt => DirtyStuff()));
    7. rootElement.RegisterCallback<ChangeEvent<bool>>((evt => DirtyStuff()));
    8. rootElement.RegisterCallback<ChangeEvent<float>>((evt => DirtyStuff()));
    9. rootElement.RegisterCallback<ChangeEvent<double>>((evt => DirtyStuff()));
    10. rootElement.RegisterCallback<ChangeEvent<string>>((evt => DirtyStuff()));
    11. rootElement.RegisterCallback<ChangeEvent<Color>>((evt => DirtyStuff()));
    12. rootElement.RegisterCallback<ChangeEvent<UnityEngine.Object>>((evt => DirtyStuff()));
    13. rootElement.RegisterCallback<ChangeEvent<Enum>>((evt => DirtyStuff()));
    14. rootElement.RegisterCallback<ChangeEvent<Vector2>>((evt => DirtyStuff()));
    15. rootElement.RegisterCallback<ChangeEvent<Vector3>>((evt => DirtyStuff()));
    16. rootElement.RegisterCallback<ChangeEvent<Vector4>>((evt => DirtyStuff()));
    17. rootElement.RegisterCallback<ChangeEvent<Rect>>((evt => DirtyStuff()));
    18. rootElement.RegisterCallback<ChangeEvent<AnimationCurve>>((evt => DirtyStuff()));
    19. rootElement.RegisterCallback<ChangeEvent<Bounds>>((evt => DirtyStuff()));
    20. rootElement.RegisterCallback<ChangeEvent<Gradient>>((evt => DirtyStuff()));
    21. rootElement.RegisterCallback<ChangeEvent<Quaternion>>((evt => DirtyStuff()));
    22. rootElement.RegisterCallback<ChangeEvent<Vector2Int>>((evt => DirtyStuff()));
    23. rootElement.RegisterCallback<ChangeEvent<Vector3Int>>((evt => DirtyStuff()));
    24. rootElement.RegisterCallback<ChangeEvent<Vector3Int>>((evt => DirtyStuff()));
    25. rootElement.RegisterCallback<ChangeEvent<RectInt>>((evt => DirtyStuff()));
    26. rootElement.RegisterCallback<ChangeEvent<BoundsInt>>((evt => DirtyStuff()));
    27.  
    a less than ideal workaround but it should work. We'll provide a better way to do this in the future
     
    Last edited: May 14, 2020
    oleg_v, CyrilGhys and Catsoft-Studios like this.
  5. BinaryCats

    BinaryCats

    Joined:
    Feb 8, 2016
    Posts:
    317
    If only ChangeEvent supported typeless override ;)
     
    Catsoft-Studios likes this.
  6. tonycoculuzzi

    tonycoculuzzi

    Joined:
    Jun 2, 2011
    Posts:
    301
    alternatively, ChangeEvent<object> could be a simple catch-all using the same syntax

    looking forward to SerializedPropertyChangeEvent, sounds like it'll be super useful! though I think an AnyFieldChanged event would be much more useful.
     
  7. Ruchir

    Ruchir

    Joined:
    May 26, 2015
    Posts:
    927
    Any updates on the topic?