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

Question Getting a direct reference or pointer to a visual element in runtime code

Discussion in 'UI Toolkit' started by RichardJanssen, Feb 22, 2021.

  1. RichardJanssen

    RichardJanssen

    Joined:
    Apr 21, 2017
    Posts:
    14
    Hi,

    Right now I am using "rootvisualelement.Query("nameOfElementIWant")" to get a reference to a visual element in runtime code. I was wondering if there are any other options to get a direct reference or pointer to a specific visual element and which one is the best practice?

    The versions I'm currently using are the following:

    Unity 2021.1.0b6.1892
    UI Builder 1.0.0-preview.12
    UI Toolkit 1.0.0-preview.14
     
    hosseinpanahlooSL likes this.
  2. TimHeijden2

    TimHeijden2

    Joined:
    Aug 11, 2016
    Posts:
    86
    I've been looking for a different solution to this as well. It is really annoying for UI designers to not be able to "rename" elements just because there are hard-coded names in code.
     
    hosseinpanahlooSL likes this.
  3. Mrbeardy

    Mrbeardy

    Joined:
    Jun 30, 2014
    Posts:
    13
    Using Query with a name to the element should be fine. If you're trying to avoid having so many Query calls throughout your code, you can store the result in a private field and reference that field whenever you need to make changes.

    Query returns a VisualElement, or you can use Q<Label>(nameOfLabel) (or any other type) to reference other element types more directly.

    Designers shouldn't really have any desire to "rename" elements though, they don't affect the visual aspects of the UI. If you're targeting your styles against the name attribute, I'd suggest using the class attribute instead.

    Having the code tightly coupled to the name of an element makes perfect sense, because if the document is changed in such a way that the element is no longer there (or is named differently), you do want the code to break, because core functionality has been changed in the UI.
     
    Last edited: Feb 25, 2021
  4. TimHeijden2

    TimHeijden2

    Joined:
    Aug 11, 2016
    Posts:
    86
    In UGUI, my UI designer often needs to change the layout based on feedback, flexibility in aspect ratio's, or changing input methods. I've made scripts that have direct references that the UI designer can also edit accordingly afterwards to make sure everything still works.

    In addition, it also makes it very clear which elements will be manipulated by code, and prevents hard-coded strings that the programmer can't find references to easily.

    As a concrete example, I want a UI designer to be able to create his own "panel" that "just works" in our view system. Right now this is achieved by placing a script on the panel, whereas with the current Query("") setup you would need a programmer to make every view, or create strings in the inspector for the UI Designer to fill in. I think that is a terrible idea & error-prone, because you have no way of knowing which references are "broken" at that point, nor would you be able to easily find which scripts manipulate which UXML's.
     
  5. Mrbeardy

    Mrbeardy

    Joined:
    Jun 30, 2014
    Posts:
    13
    That makes sense, thanks for the example. It is an interesting problem.

    I think the main benefit of GameObjects is the fact that Unity generates IDs for them under the hood, and when you pass them around as references in the editor, it's actually just referencing those IDs.

    When it comes to XML specifically, there isn't really a clean way to pull out references without adding them into the markup. This is the same for HTML and Javascript.

    I don't think it's a trivial problem to solve, as just thinking about it, when it parses the XML to build up a Tree, it's pretty ignorant to what it looked like before. It'd be really difficult to keep track of the XML nodes and assign an ID to them, because if you replace one node with another, when it comes time to parse it again, it won't actually know that the node has changed at all and it'll assume it's the same, so the references will all be messed up.

    UI Builder has an interesting part to play in this though, as it creates an abstraction from the UXML, similar to how the Unity editor creates an abstraction away from editing the scene file directly. If the UI Builder adds in those IDs into the UXML, those could be displayed and drag-dropped into other elements as references in the editor, potentially.

    I'm not an expert in any of this though, just passing my 2 cents.
     
    Last edited: Feb 25, 2021