Search Unity

Can I cache the SerializedProperty in custom PropertyDrawer.CreatePropertyGUI?

Discussion in 'UI Toolkit' started by watsonsong, Oct 9, 2021.

  1. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    Can I cache the SerializedProperty as a member variable, which will be used in the UIElements event callback?
     
  2. JuliaP_Unity

    JuliaP_Unity

    Unity Technologies

    Joined:
    Mar 26, 2020
    Posts:
    700
    Hello, what UIElements event callback are you referring to? Can you give me a more concrete example of what you're trying to achieve?
     
  3. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    For example this code:
    Code (CSharp):
    1.  
    2. [CustomPropertyDrawer(typeof(TestObj))]
    3. internal sealed class TestObjDrawer : PropertyDrawer
    4. {
    5.     private SerializedProperty boolValue;
    6.     private SerializedProperty textValue;
    7.  
    8.     private PropertyField boolField;
    9.     private PropertyField textField;
    10.  
    11.     public override VisualElement CreatePropertyGUI(
    12.         SerializedProperty property)
    13.     {
    14.         this.intValue = property.FindPropertyRelative("boolValue");
    15.         this.textValue = property.FindPropertyRelative("textValue");
    16.  
    17.         var asset = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>("Assets/TestObj.uxml");
    18.         var root = asset.CloneTree();
    19.         this.boolField = root.Q<PropertyField>("boolField");
    20.         this.textField = root.Q<PropertyField>("textField");
    21.  
    22.         this.UpdateState();
    23.         this.boolField.RegisterValueChangeCallback(e => this.UpdateState());
    24.  
    25.         return root;
    26.     }
    27.  
    28.     private void UpdateState()
    29.     {
    30.         this.textField.SetEnable(this.boolValue.boolValue);
    31.     }
    32. }
    33.  
    Is it save to save the SerializedProperty and VisualElement as a member variable in a PropertyDrawer?
     
  4. uMathieu

    uMathieu

    Unity Technologies

    Joined:
    Jun 6, 2017
    Posts:
    398
    This should be fine. However, there is an easier way:

    Code (CSharp):
    1. // ...
    2.     this.boolField.RegisterValueChangeCallback(e => this.UpdateState(e.newValue));
    3.         return root;
    4.     }
    5.     private void UpdateState(bool newBoolValue)
    6.     {
    7.         this.textField.SetEnable(newBoolValue);
    8.     }
     
    JuliaP_Unity likes this.
  5. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    So the 'RegisterValueChangeCallback' will invoke the event to initialize the state. I don't need to invoke the UpdateState once again manually?
     
  6. watsonsong

    watsonsong

    Joined:
    May 13, 2015
    Posts:
    555
    Hi, I think we can not store any widget or property as a member variable. One PropertyDrawer will reuse in multi-objects.