First, I must say that UI Elements is really starting to work for me. I’m long past the teething pains of earlier versions. It’s a pretty superior workflow.
Question: Is it best to pool all UI under one gameobject, or several? I currently mount all UI panels under one root, and then attach stylesheet unique for each document. So e.g. two info panels are two top-level children under this single root, and each has a unique stylesheet attached. The root also has a universal stylesheet attached.
I’m not having any problems, I just want to understand pros and cons with actually instantiating a unique gameobject for each major UI item, e.g. a separate gameobject for modal dialogs.
My guess is that it’s best to keep pooling, because UI Elements gets to reason about the UI from the perspective of a single root. I’d also assume that you can’t stop propagation of events in a multi-root world, so one panel would be unable block clicks from another. I’m also not sure how the render order is controlled.
Maybe this is an idiot question because I’ve never actually done multiple roots. I just wanted to affirm that single root is correct.
These are good questions, and we would like to be able to formulate good recommendations for that.
One clarification that I would like to make:
Multiple Panel Settings really mean multiple top level roots with no relation between them, hence:
– each panel has its own VisualElement root (with parent == null)
– events are dispatched once per panel (sorted with PanelSettings’s Sort order and until it’s handled)
– one panel is a least its own draw call
Multiple UIDocument components with the same PanelSettings are like VisualElements parented into the root element of the Panels, hence:
– multiple UIDocument at the same level end up producing sibling VisualElement
– multiple UIDocument are batched (when possible)
So there are 3 “levels” to think about:
Panel (via PanelSettings)
UIDocument
raw Visual Elements
While Panel vs. UIDocument has a lot of performance implications, UIDocument vs. raw Visual Elements will not make a huge difference and I would encourage using what makes the most sense for you in terms of workflow.
The extra cost to be aware of when using UIDocument is:
Disabling/enabling the GameObject owning the UIDocument releases/remove and recreates/re-adds the hierarchy
UIDocuments need to be sorted based on their sortOrder
But other than that, it’s mostly a question of preference and desired workflow, also taking into consideration how complex your game or app is and how you want things organized.
I could expand on project organization but I am under the impression that your question is mostly about performance, right?
It’s more about just developing an intuition of right and wrong. Since I have 3 completely separate panels, the question came up.
It seems to me that it’s mostly downside when having multiple gameobjects, but that it’s partly mitigated by using the same PanelSettings?
But otherwise, there’s nothing you can do with multi-root that you can’t do with single root, and you get absolute control over the stacking order, event propagation, and the draw calls and raycasting are one-stop-shop. It kind of doesn’t make sense to have a unified, hierarchical event system, and then create multiple roots that shift the whole burden back on you to make one aware of the other.
So I feel like I have my answer, one root is better.
On the issue of draw calls, is there any penalty to having large VisualElements to be used as DIVs? I find that most UI layout for me starts with my top-level nodes right under root have a VisualElement that fills the screen as the first order of business, and then items are laid out using flex inside of that.
So even if I have a button in the center of the screen, it would be wrapped in a full screen empty VisualElement with flex: column and the right alignment options to center it horizontally and vertically.
Is there a rendering penalty for very large but empty VisualElements?
No, if they are empty, they do not contribute anything to rendering. Having many empty elements can affect other systems, but once the UI is “stable” it won’t change anything to draw calls.
Like I said the UIDocument has an extra cost, but once the UI has been created, there is no distinction for UI Toolkit if the Visual Elements came from separate UIDocuments or one.
You could compare the hierarchies with the UI Debugger to get a feeling for it.
Hello Antoine. I’m just winging it right now. When certain buildings are clicked in game, relevant UI document game objects are enabled/disabled. Some of the UI take up the same location so they are divided into different documents.
It works but is there a recommended way? Any specific or general organization tips would help.