How to hook up UITooklit elements to custom events?

I use events in my game a lot.

I can invoke my custom c# events on UI clicks easily by using RegisterCallback, then invoking the event. The problem I’m having is receiving game events that need to update the UI with some game-related data at runtime.

Normally, in monobehaviours, in OnEnable I will subscribe to an event, and in OnDisable I will unsubscribe. However, with the new UI Toolkit system, there are no such methods. I first thought maybe I could do it in the OnGeometryChanged callback. However, since I think this persists between sessions, I’m getting multiple subscriptions at once. The result is that a single event invocation is received by the same UI element several times.

I suspect I’m missing something here. It occurred to me that if the UI is persistent now, it’s probably not the best place to have code that also interacts with the game. Where is the best place to reference and control UIElemements in a game. I was looking at the Battle Royale UI samples, and it seems like sometimes they put code directly into a subclass of a Visual Element, and other times they put code into a Monobehaviour manager. Although to me it’s not super clear what cause it to to be one or the other.

Could someone maybe clarify what the best way to move forward is? Should I

(A) use mono behaviour managers that need to do deep queries into the visual tree to access particualar Visual elements? This seems like I will often have script for the visual element, and a script to update it.

or should I

(B) Subclass the visual elements themselves to provide the behaviour. If so, how do I do something akin to OnEnable and OnDisable for event subscription/unsubscription

(C ) am I doing this wrong? is there a better way?

OnGeometryChanged is called every time the layout changes, so you can receive it multiple times, when the window is resized for example. Probably not what you want. The OnEnable/OnDisable equivalent would be more like AttachToPanelEvent and DetachFromPanelEvent. These events are sent when the VisualElement is attached/detached from the hierarchy.

For the rest, it really depends on what you’re trying to achieve. Both ways could work. If it can be self-contained in a subclass of the visual element, I would recommend to do that, to avoid having to pair each time a manager class for an element. But if you need some code to oversee multiple different elements, a manager querying in the UIDocument is probably a good solution.

Ah ok.Thanks a lot. I’ll try out the Attach/Detatch events. I was using the geometry event because that’s what was used in the Battle Royale demo. If it doesn’t work then maybe the mono behaviour is the way to go.

Is there a way to learn more about the different events? I haven’t been able to find any docs about it.

Thanks so much for the quick reply. Even with the quirks of being brand new with limited docs etc, the UI Toolkit and Builder are already amazing! Still a lot for me to learn though.

Documentation on event system can be found here:

And all events are listed here with some minimal information about them:

We’ll be doing a big pass on documentation soon, so pages should be clearer than they are right now. Stay tuned!

We’re happy you like it, more goodness to come!

2 Likes

I have this same question, how best to approach designing the interface. I was also using the OnGeometryChanged based on the Unity Royale sample game and I suspected it could be triggered when resizing the UI. That seems like an odd choice, not sure why the sample game is using that.

I would like to try @griendeau_unity 's self-contained method. Is there an example of that somewhere? I think many people are familiar with the OnEnable/Disable workflow and it would be helpful to compare the ‘old’ way of hooking up events and buttons to the same thing using UI Toolkit.