Update Callback

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

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.

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?

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:

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.

1 Like

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?

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().

1 Like