Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Feedback UI Toolkit Custom control best practices. Using custom control as UI manager as opposed to monobehav

Discussion in 'UI Toolkit' started by FoodFish_, Aug 15, 2023.

  1. FoodFish_

    FoodFish_

    Joined:
    May 3, 2018
    Posts:
    58
    The Unity documentation suggest that custom control should be reserved for atomic object reusable objects. However I have found that using custom control for UI manager might be viable and wanted to hear feedback. Let's say I have a QuickMenuManager : VisualElement, I have found that I could add this element to a VisualTree QuickMenu asset template I create and therefore is beneficial for encapsulation. I can then add instance of this template in my application and the code is self contained. The alternative is to add a gameObject at the root level of the UIDocument and access the VisualElement using the Q (Query) API. As you can see the QuickMenu is no longer contained in the VisualTree asset. Why is the documentation so harsh against this kind of approach?

    Unity 2023.2 Documentation:
    A good custom control is abstract, self-contained, and recurring.
    A Slide Toggle is a good example of a custom control:
    It’s abstract. You use it to switch between one setting and another.
    It’s self-contained. You give it a label and an initial value. A Slide Toggle triggers an event when its state changes.
    It’s recurring. You can use it in multiple places in an application.

    The menu bar of your application isn’t a good example of a custom control:
    It’s not abstract. It’s specific to your application.
    It’s not self-contained. It probably has dependencies on other parts of your application.
    It’s not recurring. There is probably only one menu in your application.
    After you have created a custom control, you can style it with USS and add logic to handle events in C#.

    https://docs.unity3d.com/2023.2/Documentation/Manual/UIE-create-custom-controls.html
     
    Last edited: Aug 15, 2023
  2. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    I think the docs are trying reinforce the separation between the visuals and the data. Ergo, UI is just UI. It just looks pretty and displays relevant information.

    And then your monobehaviours manage all the data and runtime stuff, as they're a part of your general Unity life cycle.

    Though to be honest I make custom controls for one-off purposes all the time, as it's often easier/quicker/more clear. That's my style though. I can see the reasoning for keeping a strict divide here and were I to work on a very UI heavy project I would probably take this approach.
     
    FoodFish_ likes this.
  3. FoodFish_

    FoodFish_

    Joined:
    May 3, 2018
    Posts:
    58
    Is runtime data binding what I am looking for? So the idea with runtime data binding would be to setup my QuickMenuManager as a MonoBehaviour and let it reference a QuickMenuDataSource scriptableobject. The QuickMenuDataSource scriptable object is then assigned to the QuickMenu corresponding VisualElement in the UI Builder? Seems like this beats accessing VisualElement from the document via string queries. Am I missing anything?

    What advantage does runtime data binding offer over custom control? It seems like just extra boilerplate.

    Discussion about runtime data binding:
    https://forum.unity.com/threads/int...ngs-api-in-unity-2023-2.1454221/#post-9223635
     
    Last edited: Aug 15, 2023
  4. martinpa_unity

    martinpa_unity

    Unity Technologies

    Joined:
    Oct 18, 2017
    Posts:
    354
    I agree with @spiney199 here, I also often make one-off custom elements because it usually makes it easier to deal with through code. I would also argue that a menu bar can be done in a way that is abstract and not application-specific. I'll bring this topic to the team. Thanks for raising this up.

    If you are using a MonoBehaviour, you can also set it as the data source of the UI Document instead of creating a ScriptableObject for it. It makes the authoring in the UI Builder a little bit more complicated (i.e. values won't be updated with the correct values), but it's one less object to maintain.

    Hope this helps!
     
  5. FoodFish_

    FoodFish_

    Joined:
    May 3, 2018
    Posts:
    58
    Thanks! What would be the advantage of using runtime data binding over a one off custom visual element as a way to script your interface then? Seems like the later is more self contained anyway.

    The only thing I see is that the runtime data binding approach lets you customize your UI without opening the UI builder. But I'm going to do that anyway when I change my UI.
     
    Last edited: Aug 15, 2023
  6. martinpa_unity

    martinpa_unity

    Unity Technologies

    Joined:
    Oct 18, 2017
    Posts:
    354
    I'd say the concerns are orthogonal.

    Creating custom visual elements usually deal with handling a sub-hierarchy and its styling and/or provide an easier way to assign UI data (i.e. setting the value of a single custom element versus querying multiple individual elements and setting their data). Runtime data binding deals with linking data with UI. The two can be used independently and they can be used together. Both are preferences in how you want to manage your UI.
     
    FoodFish_ likes this.
  7. FoodFish_

    FoodFish_

    Joined:
    May 3, 2018
    Posts:
    58
    Why would you try to link data with UI since a custom VisualElement can listen to any game event (via a singleton event container, or via ScriptableObject event container passed as reference thanks to the new object attribute for visual element) and modify the subhierarchy it wants upon hearing the callback?

    Maybe it is precisely the listening to callback and updating UI boilerplate that runtime databinding is trying to get rid of. But I am wondering if it is worth it to have to maintain the UI Manager gameObject + MonoBehaviour and UI Visual Element independently for that reason?

    As you point out, what would be a use case for a custom visual element and runtime databinding working together?

    Sorry for the insistence. It is just that coming from Unity old UI system, letting the UI submodule handle itself was very common. Now that I know that some people use one off custom control visual element as pseudo MonoBehaviour (thanks to yours and spiney199 replies) to replicate this behaviour, then this adds even more confusion since the top down approach isn't enforced as much as I thought.
     
    Last edited: Aug 15, 2023
  8. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,769
    Honestly just do what works for you. Don't get too caught up overthinking it.

    If your first approach doesn't work out, change your approach.
     
  9. martinpa_unity

    martinpa_unity

    Unity Technologies

    Joined:
    Oct 18, 2017
    Posts:
    354
    No worries about that!

    One use-case where you might want to use the bindings feature over writing the code (queries, attributes, change handling, etc.) is that you can create those links in the uxml file directly. As long as the bindings system can resolve the given paths, you can even swap data sources of different types. This can help separate the programmer and design roles.

    It can also help when you need to deal with data you didn't write and data that does not provide change handling.

    The bindings can certainly help with reducing the manual change handling and UI updating.

    However, since UI Toolkit is not MonoBehaviour-based, for game UI, most likely, you will need to maintain at least one MonoBehaviour, one Uxml document and zero or more custom elements. The bindings feature won't change that, but it provides a different way to do your setup and handle how the UI is updated.

    Here, I agree with @spiney199 once more.
     
    FoodFish_ likes this.
  10. FoodFish_

    FoodFish_

    Joined:
    May 3, 2018
    Posts:
    58
    When you explain it like that it is starting to make sense. Thank you!