Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Update Callback

Discussion in 'UI Toolkit' started by Ruchir, Jun 9, 2020.

  1. Ruchir

    Ruchir

    Joined:
    May 26, 2015
    Posts:
    934
    I wasn't able to find how to update the UI when the values of the a field changes(not from editor, for ex, during runtime or due to another script)
    Is there a callback I can use to update the UI based on the updated values as soon as they are changed instead of using
    RegisterValueChangedCallback()
    Because it didn't call the function until I change the value from inspector itself
     
  2. sebastiend-unity

    sebastiend-unity

    Unity Technologies

    Joined:
    Nov 9, 2015
    Posts:
    184
    Hi Ruchir,

    Fields are not meant to be used at runtime, maybe I am not understanding your usecase correctly?
    Also, if the value changes because of a call to
    SetValueWithoutNotify
    you will have to write custom code to your field element to get notified, otherwise I don't believe there is an easy way to do this.
     
  3. Ruchir

    Ruchir

    Joined:
    May 26, 2015
    Posts:
    934
    What I'm saying is if I have a progress bar or maybe an backgroundImage which I would like to update based on the value of multiple variable, how would I do that, the only way it get's updated is if I reSelect the gameobject with component on it for it to call the CreateInspectorGUI callback or if I use the RegisterValueChangedCallback somehow(but this one is not practical in many cases where a lot of variables are inter-dependent on each other)
    So is there a way like in IMGUI where I could reference the variable each frame to draw/Update the UI?
     
  4. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    RegisterValueChangedCallback() is for when the value is changed in the UI by the user. There's no reason to continuously poll the UI value. You still want to use this callback for monitoring the UI for changes.

    What it seems you're asking about is the opposite direction, detecting if some model/data has changed and updating the UI as a result. For this, ideally, you use the exiting binding system in Unity on top of SerializedObjects and SerializedProperties and UI Toolkit's built-in bindings system. If you're trying to monitor variables that are not serialized by Unity (and therefore cannot be part of SerializedObjects), then yes, some polling is necessary. For this I'd recommend using UI Toolkit's built-in scheduler like this:
    Code (CSharp):
    1. rootElement.schedule.Execute(() -> pollValue()).Every(100); // ms
    And update the UI if the value has changed the same why you initialize the UI's initial state.
     
    Ruchir likes this.
  5. Ruchir

    Ruchir

    Joined:
    May 26, 2015
    Posts:
    934
    From what I know I will need to put this in the CreateUI/Initialization function
    But by using this won't I be adding a callback every time it's initialized as I'm not removing the callback each time I deselect the object or close the editor, I hope you understand What I'm saying
    If this happens, then it will slow down the editor every time I select the gameObejct or whatever the UI is for
    Is there something I'm missing or a way arround this, like removing the callback when the UI is closed somehow or is this managed internally on it's own, like destroying the root element every time the UI is closed?
     
  6. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    You are in full control over when the UI is created, so you can make sure to only register for change events callback once. You must create the UI (either via C# or UXML+CloneTree()) somewhere, could be OnEnable() or in the inspector case, CreateInspectorGUI(). You should register any callbacks here, where you create the UI.

    Here's an example of a custom inspector with some event registrations both in OnEnable() and CreateInspectorGUI(). Note that CreateInspectorGUI() needs to either completely create the UI from scratch every time its called or make sure to clean up any previous UI that was created. In the example below, I create the root element in OnEnable() and then always call root.Clear() at the beginning of OnEnable().
    https://github.com/Unity-Technologi...Assets/Demo/Editor/TurretEditor_UIElements.cs
     
    Ruchir likes this.